How we encountered an unexpected bug in .NET 5, investigated the problem, and what came of it.
One fine day, it was decided to transfer a working project from .NET Core 3.1 to .NET 5. The migration turned out to be easier than it was, for example, when switching from .NET Core 2.1 to .NET Core 3 due to fewer improvements. In fact, it was just required to change TargetFramework to net5.0, update several libraries and fix a couple of places in the code that have become deprecated, so that in the future it will not be so painful to do.
, . . , , . , , HTTPS- - (401). , — . , , .NET Core 3.1, , .NET 5.
, . , HTTP Certificates, , API . , .
, - , ? curl, Python Go. .
? Windows, Linux ( , Docker). , , Docker, , , . .NET Core 3.1 , - ? , TargetFramework netcoreapp3.1, Windows, Linux.
, , ? : HttpClientFactory, HttpClientHandler , , - .
. , , , , ? , , . , .
: , , , . , , . , macOS . , .
? : . — .
: .NET, ( 5.0.2), . , . , , , .
Jetbrains Rider. (External source debug). .NET, , HTTP-, .
Windows, Linux-, :
Linux ;
WSL 2 Docker.
SSH, IDE. , Rider - , Visual Studio, .
: SecureChannel SslStreamCertificateContext. , partial : Windows , Linux — OpenSSL. SSL- SslSessionsCache. , - , .
SSL- , HTTP- :
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.First(x => x.FullName?.Contains("System.Net.Security") == true);
var cacheType = assembly.GetTypes().First(x => x.Name == "SslSessionsCache");
var field = cacheType.GetField("s_cachedCreds", BindingFlags.NonPublic | BindingFlags.Static);
if (field != null)
{
var dic = (IDictionary?) field.GetValue(null);
dic?.Clear();
}
( . - .)
, , SSL-, . : EventSource.
EventSource
.NET Core 3.0, Linux EventSource — , , . :
EventListener, ( , , csv-);
-
, csv, , :
.NET Core 3.1 Windows 10
.NET Core 3.1 Linux
.NET 5 Windows 10
.NET 5 Linux
, , , :
:
HTTP- 3.1 5.0. , managed SocketsHttpHandler (, Linux libcurl). 3.1, AppContext, ;
;
Windows Linux, .
. , ...
, , — .NET. .NET Github, issue Pull Request.
issue , .
issue
Issues , , , . , - SSL- Http-, , area-System.Net
area-System.Net.Security
.
issue , , , , Github Stack Overflow, , , Hello World . , , issue , issue , .. , , .
, , issue . , , :
: - , — , ;
.
.
API , , .
,
, , , nginx - . .NET, , C#, ASP.NET Core Kestrel. .
, (, );
Kestrel, .
ASP.NET Core , . , - -, , , . Go, , . , :
func main() {
caCert, err := ioutil.ReadFile("ca.cer")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
cfg := &tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
//ClientCAs: caCertPool,
}
srv := &http.Server{
Addr: ":8443",
Handler: &handler{},
TLSConfig: cfg,
}
log.Fatal(srv.ListenAndServeTLS("certificate.cer", "private.key"))
}
type handler struct{}
func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("PONG"))
}
HTTP-, . Go net/http PFX- , , . , (CA). , , . , , , .
Go . , 401, , , . :
http: TLS handshake error from 127.0.0.1:56082: tls: failed to verify client's certificate: x509: certificate signed by unknown authority
, .
— (CA) , - . , CA, , (Chain of Trust) CA, . , , . .
, . TLS- Server hello, , :
- , (, , ), , .
PFX-. PFX- :
( );
, . , PFX- ;
, .
PFX- , , OpenSSL:
openssl pkcs12 -in certificate.pfx -clcerts -nokeys | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > certificate.cer
openssl pkcs12 -in certificate.pfx -cacerts -nokeys -chain | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ca.cer
openssl pkcs12 -in certificate.pfx -nocerts -nodes | sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' > private.key
PFX- , . PFX- :
openssl pkcs12 -export -out certificate.pfx -in certificate.crt -certfile ca.crt -inkey privateKey.key
, Go , .NET PFX-, , . , .NET 5 X509Certificate2, .
,
CA, , CA, CSR- (Certificate Signing Request). (extensions), . , , . , SCT , . , .
, , , :
.
, ( ), — . - , .. ;
. ?
Let's Encrypt.
, , .
Let's Encrypt.
Let's Encrypt
Let's Encrypt PFX- .NET 5, — Go, . ! ! , !
, Microsoft. , . issue , , , , .
?
Tomas Weinfurt, Microsoft, , , .NET, SSL. Pull Request, , , ( , ). PR master- ( .NET 6), 5.0. 5.0.4.
. , .NET 5 SslStreamCertificateContext, issue, 3.1. SSL-, , , , , .
, , - , , , . Go , , . Go net/http , .
, / , , :
, ;
, . , , ;
Stack Overflow - , ;
, , ( , );
, , .
.NET , , , ( , , ). .NET 5 C# 9.0, records code generators.
, , Microsoft .NET , Github. .NET , .
, . , , , , . , - .
Thanks to @tycheg for helping with initial reproduction and debugging of the problem.