gRPC Server Deployed in Container Cannot Establish SSL Connection - .net-core

I am trying to deploy a simple grpc server written in asp.net core. The Kestrel settings are
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(c =>
{
c.Listen(IPAddress.Any, 8001);
c.ConfigureHttpsDefaults(https =>
{
https.ServerCertificate = new X509Certificate2("MyDemo.gRPC.pfx", "Pa55word");
});
})
.UseStartup<Startup>();
});
I have created a docker image and deployed it to an Azure Container Instance, and exposed port 8001. When I use an insecure channel to call the server from a client, I get a successful response, i.e
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
using var channel = GrpcChannel.ForAddress("http://01.02.3.04:8001");
gets the server to respond. However, when I try to use a secure channel and use https, I get the exception
Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. IOException: The handshake failed due to an unexpected packet format.
I presume that it is something to do with my Kestrel settings, can anyone see my problem?

Related

SignalR client receives Information: Connection disconnected from hub

I created a signalR JavaScript client that needs to communicate with a hosted signalR server (from Playfab). I successfully created the signalR client and connected it with the server, but the problem that I'm facing is that the connection doesn't stay open more than 30 seconds even though I subscribe to events.
Here are the messages between the client and server. After one ping, the server sends a close message.
Messages between client and server
How can I prevent this from happening?
Here is how the connection is created
connection = new signalR.HubConnectionBuilder()
.withUrl(`url`, {
withCredentials: false,
httpClient: new SignalRClient(),
headers: {
'X-EntityToken': entity.EntityToken,
},
})
.build()
await connection.start()

asp.net header forwarding not working for external Identity provider

I use asp.net Identity with AzureAD as an external Identity provider in my Balzor server side app. In development environment (localhost) logging in works fine. When I deploy the app to an on premise server in a docker image behind Nginx, it does not. Microsoft sends the error message AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application. I have added the proper reply URL to Azure portal. As far as I can tell, the request uses http, while https should be used, which causes the error.
Since Nginx handles secure transport, the headers need to be forwarded, so I configured Nginx and enabled Header forwarding in Startup.ConfigureServices:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.ForwardLimit = 1;
options.KnownProxies.Add(IPAddress.Parse("123.xxx.xxx.xxx"));
});
and at the very beginning of Startup.Configure:
app.UseForwardedHeaders();
app.UseHsts();
// should not be necessary but I tried with and without
//app.UseHttpsRedirection();
When I enable logging, I think I see that the correct header is forwarded from Nginx:
...
Header: X-Forwarded-For: 123.xxx.xxx.xxx
Header: X-Forwarded-Proto: https
...
To me it looks like ChallengeResult() in ExternalLogin.Post is not using the forwarded headers and sends http://my.domain.ch/signin-oidc instead of https:// as reply URL, which causes the error.
I ran out of ideas what else I could try, any suggestions please?
After some digging I found the mistake: I did add the wrong proxy IP. Since my asp.net app is hosted on docker, I had to add the IP address of the docker image as proxy, not the IP of the server which hosts nginx and docker. In fact, I added the default network used by docker
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("172.17.0.0"), 16));

Can't access the http server in VPS

I have server on digitalocean. There was running nginx. I killed all nginx processes and created simple node.js http server:
const http = require('http');
http.createServer((req, res) => {
console.log('requeeeeest');
res.end('hello world');
}).listen(80, '0.0.0.0', () => { console.log('listening'); });
But when I run my server, I cannot connect to it. My request is
perennially waiting. Also to whatever port I try to connect - there is perennial request waiting. Why ports are "running"? And why I cannot connect to my node.js server. By the way, my server is accessible from localhost.
This is due to the firewall was running.

How to connect DataSnap client to DataSnap server via proxy server?

The problem is this:
I decided to make a messenger/chat (VCL application) with callback on DataSnap technology (IDE Delphi XE6), has created a simple DataSnap server (tcp / ip + http) without the database, and thick client.
All works fine if the whole thing run on a local network (tcp / ip) or via the Internet (http).Problems arise when run over HTTP and the client machine has a HTTP proxy server, the client application can not connect to my DataSnap server application. Client application gets error "10061 connection refused"
or "Expected datasnap context in request http://[YourServerIP]:[YourPort]/datasnap/tunnel".
I tried to enter IP and port of the proxy server to params of component TSQLConnection.Driver params DSProxyHost and DSProxyPort, turned off my firewall and antivirus software, checked allows traffic to the proxy ip + port, but the problem has not disappeared.
After few days searches, without results, i decided listening requests from client application and response of my DataSnap Server application in HTTPTrace procedure of DSHTTPService1 component, also with software HTTPDebugerPro, and i noticed interesting thing:
when client app connecting to ds server app without proxy server, in request ds server app receive URI with this text "/datasnap/tunnel" and all works fine ds server response "200, OK".
when client app connecting to ds server app with proxy, in request ds server app receive URI with text "http://[YourServerIP]:[YourPort]/datasnap/tunnel" and raised exception with response error "404, Expected datasnap context in request http://YourServerIP:YourPort/datasnap/tunnel".
Has anyone knows solution about this problem? How to connect DataSnap client to DataSnap server via proxy server? I searched solution for this problem several days, I shoveled the Internet but have not yet found a solution.

Websocket hosted in ASPNET Core RC2, IIS "WebSocket connection to 'wss://xxx' failed: Error during WebSocket handshake: Unexpected response code: 302

I have a web socket server hosted in ASPNET Core RC2.
It works fine on my local dev box, when running on just kestrel, and also when kestrel is hosted in IIS.
When Google Chrome is used to connect to the websocket server, it works OK on local box, and on remote box:
JavaScript:
new WebSocket("wss://myServer:8087")
However when the JavaScript is connecting to the same server, hosted on our build machine (OS: Server 2008 R2) the client gets this 302 (redirect) error:
WebSocket connection to 'wss://myBuildServer:8087/' failed: Error during
WebSocket handshake: Unexpected response code: 302
note: when the JavaScript is running on Chrome on the server itself, the error is different:
WebSocket connection to 'wss://xxx:8087/' failed: WebSocket opening handshake was canceled
C# source that adds web sockets (Microsoft.AspNetCore.WebSockets.Server 0.1.0-rc2-final):
private void ConfigureWebSockets(IApplicationBuilder app)
{
DPT2.Web.Utils.Logger.Log("ConfigureWebSockets()");
_socketHandler = new Sockets.WebSocketHandler(_nodeServices);
app.UseWebSockets(new WebSocketOptions{
//try to fix 302 redirect on build m/c:
ReplaceFeature = true,
//TODO tune via these params:
KeepAliveInterval = TimeSpan.FromMinutes(2),
ReceiveBufferSize = 4 * 1024
});
app.Use(async (http, next) =>
{
if (http.WebSockets.IsWebSocketRequest)
{
var webSocket = await http.WebSockets.AcceptWebSocketAsync();
if (webSocket != null && webSocket.State == WebSocketState.Open)
{
await _socketHandler.Handle(webSocket);
}
}
else
{
// Nothing to do here, pass downstream.
await next();
}
});
}
It looks like the request is being 'corrupted' somehow, and this C# line does not recognise it as a web socket request, and so passes it on to MVC:
if (http.WebSockets.IsWebSocketRequest)
versions:
Server OS: Windows 2008 R2
IIS 6.1 build 7601 - SP1
IIS Manager 7.5.7600.16385
installed the ASPNET Core hosting: DotNetCore.1.0.0.RC2-WindowsHosting.exe
I've tried a few workarounds:
using http for the site, and ws:// for the web socket URL
using https for the site, and wss:// for the web socket URL
adding the ReplaceFeature option to the websocket server
Has anyone else seen a similar issue ?
I think its to do with IIS acting as a reverse proxy for kestrel, and perhaps on that particular machine, the proxying is messing up the web socket request ...
It could be a configuration issue on the server ...
Sean

Resources