SignalR on kubernetes with let's encrypt ingress service

1/23/2019

I have dotnet core signalR application on kubernetes services. On top of that, lets encrypt ingress service provides me SSL certificate.

I can get web site under Let's encrypt certificate and everything seems valid.

If I want to connect signalR by wss protocol, every 2 seconds connection is dropped.

Error is :

{"error":"Handshake was canceled."}
The connection was terminated cleanly with status code 1000 (NORMAL).

Server log is :

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://DOMAIN/ChatHub  
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionManager[1]
      New connection XPqUHoK9b4PAeF_bKwQtIg created.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionDispatcher[4]
      Establishing new connection.
dbug: Microsoft.AspNetCore.SignalR.HubConnectionHandler[5]
      OnConnectedAsync started.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.Transports.WebSocketsTransport[1]
      Socket opened using Sub-Protocol: '(null)'.
dbug: Microsoft.AspNetCore.SignalR.HubConnectionContext[2]
      Handshake was canceled.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.Transports.WebSocketsTransport[7]
      Waiting for the client to close the socket.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.Transports.WebSocketsTransport[2]
      Socket closed.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionManager[2]
      Removing connection XPqUHoK9b4PAeF_bKwQtIg from the list of connections.

Application Versions:

netcoreapp2.2
Microsoft.AspNet.SignalR -v 2.4.0

I tried also pure websocket connections but it was same. How can I solve this issue?

PS: It was worked if I defined physical SSL certificate to kestrel server.

-- Mert Demir
.net-core
asp.net-core
kubernetes
lets-encrypt
signalr

1 Answer

3/14/2019

I had similar issue and this is how I managed it note : this solution is a working solution for pure websocket in dotnet core 2.2 i have not test it with signalR

use Apache as proxy Microsoft doc here

<IfModule mod_ssl.c>
<VirtualHost *:443>
  ProxyPreserveHost On
  RewriteEngine On
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)           ws://127.0.0.1:81/$1 [P,L]
  RewriteCond %{HTTP:Upgrade} !=websocket [NC]
  RewriteRule /(.*)           http://127.0.0.1:81/$1 [P,L]

    ProxyPass / http://127.0.0.1:81/
    ProxyPassReverse / http://127.0.0.1:81/
</VirtualHost>
</IfModule>

so basically what will happen is the traffic will be HTTPS till the Apache and then Apache will act as proxy and hand the traffic to the Kestrel. it may seam hard to configure but it's not,

  • configure the Apache to work with HTTP & WS then configure the let's encrypt like this :
sudo add-apt-repository ppa:certbot/certbot
sudo apt install python-certbot-apache
sudo nano /etc/apache2/sites-available/example.com.conf
...
ServerName example.com;
...
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo ufw allow 'Apache Full'
sudo ufw delete allow 'Apache'

the next line of command will configure your SSL Apache configuration

sudo certbot --apache -d example.com -d www.example.com

then you will be able to access to your site via HTTPS & WSS,It never failed till now :)

-- Ali Alp
Source: StackOverflow