dotnet / HttpRepl

The HTTP Read-Eval-Print Loop (REPL) is a lightweight, cross-platform command-line tool that's supported everywhere .NET Core is supported and is used for making HTTP requests to test ASP.NET Core web APIs and view their results.
MIT License
699 stars 69 forks source link

"HttpRequestException: The SSL connection could not be established" under Linux #326

Open artkpv opened 4 years ago

artkpv commented 4 years ago

Hello, I'm having this error when running under ArchLinux. Created a project "webapi" under dotnet 3.1, dotnet new webapi. Run it with dotnet run. Then I connect to it using HttpRepl and it throws this exception. How to fix?

https://localhost:5001/> get 1
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
   at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
   at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslStream.ThrowIfExceptional()
   at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)
   at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
   at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.HttpRepl.Commands.BaseHttpCommand.ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput`1 commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken) in /_/src/Microsoft.HttpRepl/Commands/BaseHttpCommand.cs:line 142
   at Microsoft.Repl.Commanding.DefaultCommandDispatcher`2.ExecuteCommandInternalAsync(IShellState shellState, CancellationToken cancellationToken) in /_/src/Microsoft.Repl/Commanding/DefaultCommandDispatcher.cs:line 150
   at Microsoft.Repl.Commanding.DefaultCommandDispatcher`2.ExecuteCommandAsync(IShellState shellState, CancellationToken cancellationToken) in /_/src/Microsoft.Repl/Commanding/DefaultCommandDispatcher.cs:line 113

Environment:

[I] ➜ uname -a  
Linux artpc 5.5.3-arch1-1 #1 SMP PREEMPT Tue, 11 Feb 2020 15:35:41 +0000 x86_64 GNU/Linux

art on  master [!] 
[I] ➜ dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   3.1.100
 Commit:    cd82f021f4

Runtime Environment:
 OS Name:     arch
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /usr/share/dotnet/sdk/3.1.100/

Host (useful for support):
  Version: 3.1.0
  Commit:  6e49edcd54

.NET Core SDKs installed:
  3.1.100 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.App 3.1.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
tlmii commented 4 years ago

@artkpv Are you able to access the web api via a web browser with no certificate errors? I'm not too familiar with how certs are handled on linux, but my guess would be that the self-signed cert for the web api is not trusted.

artkpv commented 4 years ago

@tlmii Firefox v73 disables certification check for localhost by default so yes, it accesses the api. Looks like I need to issue a certificate for localhost and make HttpRepl use it.

BTW, curl also works only if I disable security checks (-k switch).

kipters commented 4 years ago

I'm facing the same issue, but even after trusting my local certificate (i.e. curl works without -k) I still get this exception with httprepl

bradygaster commented 4 years ago

@kipters were you able to resolve this per the workaround @artkpv mentioned?

kipters commented 4 years ago

@bradygaster I ended up generating a new cert and using that one instead of the one generated by netcore itself for my server, using this one everything works as expected:

#!/bin/bash

if [[ "$1" != "" ]]; then
    CERTNAME="$1"
else
    CERTNAME=cert
fi

openssl req -x509 -newkey rsa:4096 -keyout ${CERTNAME}_key.pem -out $CERTNAME.pem -days 365
openssl pkcs12 -export -out $CERTNAME.pfx -inkey ${CERTNAME}_key.pem -in $CERTNAME.pem
openssl pkcs12 -in $CERTNAME.pfx -clcerts -nokeys -out $CERTNAME.crt
bradygaster commented 4 years ago

@kipters and @tlmii - I tried this in an effort to validate if this trick would also fix my issue in which i'm seeing the repl be unable to get to the actual swagger JSON URL. it's there, and I can call it, but just like I showed @tlmii with the Tye demo, I can't access my swagger endpoint when i'm running SSL.

tlmii commented 4 years ago

@bradygaster I removed the waiting tag since we're not waiting on a customer - do we need to do anything else here? I can't remember if you ended up unblocked or not.