6

I created a small demo project for SignalR. It all worked when I published my project behind Nginx without SSL. But after I ran Certbot and added SSL to the site all SignalR hubs / WebSockets stopped working. The site can be found here:

https://app.topswagcode.com

signalr.js:5053 WebSocket connection to 'wss://app.topswagcode.com/chatHub?id=v_UmTZyB9v962n44Wf2-Kg' failed: 
(anonymous) @ signalr.js:5053
(anonymous) @ signalr.js:5034
step @ signalr.js:4995
(anonymous) @ signalr.js:4976
(anonymous) @ signalr.js:4970
__awaiter @ signalr.js:4966
WebSocketTransport.connect @ signalr.js:5016
HttpConnection.startTransport @ signalr.js:4149
(anonymous) @ signalr.js:4099
step @ signalr.js:3710
(anonymous) @ signalr.js:3691
(anonymous) @ signalr.js:3685
__awaiter @ signalr.js:3681
HttpConnection.createTransport @ signalr.js:4052
(anonymous) @ signalr.js:3970
step @ signalr.js:3710
(anonymous) @ signalr.js:3691
fulfilled @ signalr.js:3682
signalr.js:2150 [2021-06-11T06:43:20.004Z] Error: Failed to start the transport 'WebSockets': Error: There was an error with the transport.

My API Endpoints still works and SSL seems to be working in general.

For deploying my app I followed: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0

ran smoothly for normal HTTP connections. Certbot added its SSL stuff and broke my WebSockets :(


Edit

So I tried to revert all changes and start over. Instead of redirecting all traffic to SSL (which I should), I have both HTTP and HTTPS

http://app.topswagcode.com/Stock

https://app.topswagcode.com/Stock

Again my Http sockets still works, but HTTPS doesn't.

My Nginx Setup:

server { 
    server_name app.topswagcode.com; 
    location / { 
        proxy_pass http://127.0.0.1:5000; 
        proxy_http_version 1.1; 
        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host; 
        proxy_cache_bypass $http_upgrade; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /chathub { 
        proxy_pass http://127.0.0.1:5000/chathub; 
        proxy_http_version 1.1; 
        proxy_set_header Host $host; 
        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Host $server_name; 
        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection "upgrade"; 
        proxy_cache_bypass $http_upgrade;
}


    listen 80; # managed by Certbot

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/app.topswagcode.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/app.topswagcode.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

I tried to add a chat hub section that I found in some posts. But Didn't do anything for SSL.

API endpoint's still working for both HTTP and HTTPS. Still lost about what I did wrong. Most likely something simple in the Nginx config.

For the sake of it, I will be sharing my Startup.cs below here as well. Not much special in id. I have disabled the app.UseHttpsRedirection(); and app.UseHsts();

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        services.AddControllers();
        services.AddSignalR();

        services.AddTransient<IStockService, FakeStockService>();
        services.AddHostedService<TimedHostedService>();
        services.AddHostedService<StockHostedService>();
    }


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            //app.UseHsts();
        }

        //app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });


        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllers();
            endpoints.MapHub<ChatHub>("/chathub");
            endpoints.MapHub<ProcessHub>("/processhub");
            endpoints.MapHub<GraphHub>("/graphhub");
            endpoints.MapHub<StockHub>("/stockhub");
        });
    }

Edit 2

So I just found this:

enter image description here

enter image description here

This request fails only for Https. Request body is:

{"protocol":"json","version":1}

But for HTTPS, it just returns: Not found "No Connection with that ID"

Sam Joshua
  • 310
  • 6
  • 17
Kiksen
  • 1,559
  • 1
  • 18
  • 41
  • Have you checked firewall? You need to have port 443 (TCP) open. – anemyte Jun 14 '21 at 05:50
  • Yep. SSL is working for All except websockets. Razor pages are derved using SSL and API is derved using SSL. – Kiksen Jun 14 '21 at 17:20
  • Hi @Kiksen sounds like a weired problem with foroworded headers and schema... had something similar with sharepoint one day. You can register in our community slack nginxcommunity.slack.com and reach out to me. alternatively discord. Would like to debug and it and create a writeup afterwards. – Timo Stark Jun 15 '21 at 06:39
  • @TimoStark > I Think I will join one of the following days. Currently on vacation and this is just a hobby project :) But still really strange. I tried using the SSL Certs directly in AspNetCore and got sockets working for SignalR this way. Still looking into why Nginx setup isn't working. – Kiksen Jun 15 '21 at 19:52
  • Are you running this project on Windows server? – thelovekesh Jun 19 '21 at 09:19
  • @LovekeshKumar > No. On Ubuntu Arm64 – Kiksen Jun 21 '21 at 12:36

2 Answers2

0

In Startup.js / ConfigureServices: ​

services.AddSignalR(options => {
    ​options.KeepAliveInterval = TimeSpan.FromSeconds(15);
    ​options.EnableDetailedErrors = true;
​});

In Startup.js / Configure:

app.UseWebSockets();
app.UseStaticFiles();
A.J.Bauer
  • 2,803
  • 1
  • 26
  • 35
0

Unfortunately i totally failed with various custom ssl validation callbacks implementations client-side, so only the server-side solution worked for me:

https://github.com/xamarin/xamarin-android/issues/6351#issuecomment-931987612

(if the link goes down its basically silly deleting the last certificate from 3 present inside your domain fullchain.pem file)

Another solution: https://github.com/xamarin/xamarin-android/issues/6351#issuecomment-946178743

Do not forget to deamon-reload and restart nginx after.

Nick Kovalsky
  • 5,378
  • 2
  • 23
  • 50