SignalR Core Apache WS Unexpected response code: 200 - signalr

I'm currently running a .Net Core application with SignalR on an Ubuntu Apache web server. This .Net Core app is reachable by the example.com/api path.
I also have a Vue JS app running on the webserver as well. When I attempt to establish a websocket connection to the the SignalR application, the following error occurs:
WebSocket connection to 'wss://example.com/api/mainHub?id=V3XZrhdsQDTTMIZvQ-8cbQ' failed: Error during WebSocket handshake: Unexpected response code: 200
Error: Failed to start the transport 'WebSockets': null
The Apache config for the .Net Core app is as follows:
#Main/Desired Path - https://example.com
<VirtualHost *:443>
DocumentRoot /var/www/example.com/dist/spa
ServerName example.com
#SSL Certs
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
SSLCertificateFile /etc/apache2/ssl/example.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/example.ca-bundle
#Upgrade Websockets
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P]
#Other specific directories
ProxyPreserveHost On
ProxyPass "/api" http://localhost:5000
ProxyPassReverse "/api" http://localhost:5000
</VirtualHost>
I've added the RewriteEngine to upgrade the websockets, I'm not sure if the issue is with the configuration on Apache, or in the .Net Core app itself.
The .Net Core app has the following in the startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options => options.AddPolicy("CorsPolicy", builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins("*");
}));
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//first handle any websocket requests
app.UseWebSockets();
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<mainHub>("/mainHub");
routes.MapHub<accounthub>("/accountHub");
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
It seems that either something is incorrect in the startup.cs that is sending a 200 response back to the client when establishing the websocket connection or the Apache virtual host is not properly upgrading the websocket.

I have found this on a site ( http://shyammakwana.me/server/websockets-with-apache-reverse-proxy-with-ssl.html ) which seems to work also for me.
The apache config for the given site should be like this
<IfModule mod_ssl.c>
<VirtualHost *:443>
RewriteEngine On
ProxyPreserveHost On
ProxyRequests Off
# allow for upgrading to websockets
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:5000/$1 [P,L]
ProxyPass "/" "http://localhost:5000/"
ProxyPassReverse "/" "http://localhost:5000/"
ProxyPass "/chatHub" "ws://localhost:5000/chatHub"
ProxyPassReverse "/chatHub" "ws://localhost:5000/chatHub"
ServerName site.com
SSLCertificateFile /etc/letsencrypt/live/site.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/site.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Also you should have these modules enabled:
a2enmod proxy
a2enmod proxy_wstunnel

I am also getting this error while deploying a ASP.NET Core 3.1 Blazor Server-side app to an Ubuntu 18.04 server running Apache2.
In combination with this error, I am also getting a 404 error trying to access static resources (.css files, images and scripts) from the Linux server, but everything works perfectly in an IIS environment. I've also noted that the contents of the WWWRoot folder in my solution do not appear to be copied to the linux server when I publish the app. I am using the FolderProfile method of publishing, then copying the contents of the publish folder to the linux server via SFTP.
The only "real" change from the boilerplate startup.Configure class (from the New Blazor-Server Web App template in VS2019) I have made is to add the UseForwardHeaders directive as described at https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-3.1
I've also added Authentication and Authorisation to the app, but once again, the whole thing runs perfectly on IIS, but it needs to be installed on a production linux server once testing is complete.
My Startup.Configure looks like:
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
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();
}
// Enable SyncFusion Community Edition License
Syncfusion.Licensing.SyncfusionLicenseProvider
.RegisterLicense("Key-Removed");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
// Use Authentication and Authorisation providers in the application
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
Also, on the linux side, the virtual host configuration file looks like this:
#<VirtualHost *:*>
# RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
#</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ServerName www.grafton.internal
ErrorLog ${APACHE_LOG_DIR}labapp_error.log
CustomLog ${APACHE_LOG_DIR}labapp_access.log common
</VirtualHost>
Note I have commented out the top 3 lines because I could not get this expression to work correctly - Apache failed to start with every variation of the 2nd line I tried. I believe this might be related to my problem, but I am not sure what to do about it.
I also want to stress that this app is for internal use only, and the web server is only visible on our Intranet - there are no external / internet facing servers or sites and access is limited to a very few people via physical access to the servers, and restricted fixed IP addresses, so I am not at all concerned with using SSL.
Any assistance with this one would be appreciated. I've been trying to get this running for a week, and only have a week left before it MUST be in the linux test environment.

Related

Blazor Server cannot interact with components

I've made a simple app in Blazor Server, and it works fine for the most part except for when I attempt to run it on my VPS with HTTPS. When I run the app no errors appear, and the websocket appears to connect successfully (viewed from the Firefox console), and yet I cannot interact with any of the components on the website. The websocket doesn't send over any anything when attempting to interact with the components either, but it keeps heartbeating.
I've made a brand new Blazor Server project and followed the following guide: https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/server, but to no avail.
The VPS runs on Ubuntu 22.04.1 LTS, Apache2 as the webserver (attemped using nginx, didn't help), and Cloudflare as the CA.
The certificate and key are correct and not outdated.
I'm running this virtual host (taken from the link above, and additionally from https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-6.0 (tried just using the configuration from the first link, didn't work)).
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
<VirtualHost *:443>
ServerName <serverName>
Protocols h2 http/1.1
ProxyRequests On
ProxyPreserveHost On
ProxyPassMatch ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass /_blazor ws://localhost:5000/_blazor
ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder off
SSLCompression off
SSLSessionTickets on
SSLUseStapling off
SSLCertificateFile /home/cf.pem
SSLCertificateKeyFile /home/cf.key
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:>
</VirtualHost>
This is how the Blazor Server main looks like (the snippet that's commented out I've tried, didn't help):
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
//builder.WebHost.ConfigureKestrel(options =>
//{
// options.ConfigureHttpsDefaults(options =>
// {
// var pem = File.ReadAllText(builder.Configuration["PemPath"]).Trim();
// var key = File.ReadAllText(builder.Configuration["KeyPath"]).Trim();
// var crt = X509Certificate2.CreateFromPem(pem, key);
// options.ServerCertificate = crt;
// });
//});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseForwardedHeaders(new() { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto });
app.UseAuthentication();
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
}
To confirm: I'm able to access the website via HTTPS, the HTTPS connection is successful, no Razor component I interact with does anything.
Any help or tips on how to proceed would be greatly appreciated, thank you!
I've solved the issue.
If anyone else comes by this having a similar issue, check with your CA (Cloudflare in my case) a setting called "auto-minify" (or similar) which minimizes your HTML, CSS, and Java.
The article that helped me solve my issue: https://zimmergren.net/solved-asp-net-core-blazor-web-sites-does-not-work-with-cloudflare-html-minification/

The web application does not display using apache server in linux

I am trying to create a web application using dotnet 3.1 and httpd 2.4 with a proxy server but no mater what how the configuration files are the web application is not displayed.
I am using a Fabian with rhel 7.
The following are the configuration file located in the folder /etc/httpd/conf.d/,
<VirtualHost *:80>
ServerName 22.xx.xxx.xx
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://127.0.0.1:5000/$1 [P]
ErrorLog /var/log/httpd/netcore-error.log
CustomLog /var/log/httpd/netcore-access.log common
</VirtualHost>
My service file located at /etc/systemd/system and is as follows, i hade ensure that the location of the dotnet location is as follows as it was not installed in the standard location. Additionally the root user has been given all required permission
[Unit]
Description=ASP .NET Web Application
[Service]
WorkingDirectory=/var/netcore/publish
ExecStart=/opt/rh/rh-dotnet31/usr/bin/dotnet /var/netcore/publish/Test.dll
Restart=always
RestartSec=10
SyslogIdentifier=netcore-demo
User=root
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
Additional info:
-The error log at location /var/log/httpd/netcore-error.log displays no errors but I no the server has atleast received a request from the following log in the access log
-The access log only shows the following 22.xx.xxx.xxx -- [Date and Time] "GET /HTTP/1.1" 307 -
I have turned of the firewalld.service and configured the IPtable.
When I use curl, there is no response.
Dotnet is listening in port 5000 and 5001, not sure why?
Apache is listening in port 80
When run the application from with dotnet command it seem to work, there does not seem to a problem with the application.
Have tried without specifying the server name and still had no change
Any help would be appreciated as have been stuck on this problem for 2 weeks now.
Just an update - turns out it was a problem with the code/configuration. I think it was called launchsetting.json file, which forcefully made the connection a HTTPS and forward it to the wrong port. Just had to remove that section and all was good.

Shiny-Server with Apache WebSocket fail

I'm new to servers. I installed an Apache web server on Ubuntu 20.04, with and secured the connection with Let's Encrypt. Then I set up a Shiny server (latest Version) and set up the following forwarding in Apache (according to the template).
<Proxy *>
Allow from localhost
</Proxy>
RedirectMatch permanent ^/app$ /app/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /app/(.*) ws://localhost:3838/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /app/(.*) http://localhost:3838/$1 [P,L]
ProxyPass /app/ http://localhost:3838/
ProxyPassReverse /app/ http://localhost:3838/
Header edit Location ^/ /app/
ProxyRequests Off
I can call up my Shiny-app on my mobile phone as well as on the desktop at home (everything works). In our company network, it loads the website first, but not the interactive parts - and then the entire page turns gray.
Based on research, it appears to be a problem with the websockets and the firewall oft the company. The same app on shinyapps.io works. I can find the following error message in the web browser:
sockjs-0.3.4.min.js:27 WebSocket connection to 'wss://srv.socialthink.net/app/uster-kultur/__sockjs__/n=kNUaoWz4VkbEoGT2f8/464/b_7zv2u0/websocket' failed:
I found a similar description of the problem, but no workaround to fix the problem.
I don't know how to continue looking, are there any ideas?

Setup Centrifugo server with apache virtual host and ssl

I know most people do it backwards (apache to nginx), but the server where this project is hosted has other projects with particular configurations so... it's better to stick with what we have
What I'm trying to accomnplish is migrate an nginx virtual host configuration, for the centrifugo golang messaging server, to apache2.4 from the docs example
This is what I have
#### This part it's commented because the server says it has incorrect syntax
# <Proxy "balancer://centrifugocluster"> {
# Enumerate all upstream servers here, in case you want to clusterize
# BalancerMember http://127.0.0.1:8000 # default host and port, change it if need it
# BalancerMember http://127.0.0.1:8001;
# </Proxy>
# ProxyPass / balancer://centrifugocluster/
<VirtualHost *:80>
ServerName centrifugo.MY_HOSTING.com
Redirect permanent ^(.*) https://centrifugo.MY_HOSTING.com/$1
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName centrifugo.MY_HOSTING.com
SSLEngine On
SSLCertificateFile /PATH/TO/CRT/FILE.crt
SSLCertificateKeyFile /PATH/TO/KEY/FILE.key
SSLCertificateChainFile /PATH/TO/CHAIN/FILE.crt
<Location "/connection/">
# Required for websockets
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule /connection/(.*) http://127.0.0.1:8000/connection/$1 [P,L]
</Location>
<Location "/">
ProxyPass http://127.0.0.1:8000/
ProxyPassReverse http://127.0.0.1:8000/
</Location>
ErrorLog ${APACHE_LOG_DIR}/PATH/SERVER_LOG/FILE.log
CustomLog ${APACHE_LOG_DIR}/PATH/ACCESS_LOG/FILE.log combined
#### This part I'm not sure how to translate it
ErrorDocument 500 "Server Error 500"
ErrorDocument 502 "Server Error 502"
ErrorDocument 503 "Server Error 503"
ErrorDocument 504 "Server Error 504"
</VirtualHost>
</IfModule>
the server has apache2.4 and ubuntu18, the centrifugo config is
{
"secret": "SECRET",
"admin_password": "PASSWORD",
"admin_secret": "ADMIN-SECRET",
"api_key": "API-KEY",
"engine": "memory",
"admin": true,
"debug": true,
"log_level": "debug"
}
current behavior
the url it's redirected to https succesfully, other projects works good with the ssl config
all directories path are checked and correct
but it says 404 page not found
when I try on the browser centrifugo.MY-HOST.com does show this 404 error
when I try with websocat library (from outside the server) websocat ws://centrifugo.MY-HOST.com/connection/websocket it says WebSocketError: Received unexpected status code. Error running
when I try with websocat library (from INSIDE the server, i mean connected by ssh) websocat ws://localhost:8000/connection/websocket it hangs... (waiting for messages I believe)
the centrifugo server it's up and listening port 8000, checked with netstat and supervisor says running
I changed 127.0.0.1 to localhost in the centrifugo config and the virtual host, added documentRoot to the path of the apache project and nothing...
what i'm doing wrong?
Never mind, it was my mistake in supervisor configuration. I had this:
[program:centrifugo]
command=sudo /var/www/centrifugo-server/centrifugo
autostart=true
autorestart=true
stderr_logfile=/var/log/centrifugo.error.log
stdout_logfile=/var/log/centrifugo.output.log
I placed the config file with full path to it and remove the sudo, and it works like a charm
command=/var/www/centrifugo-server/centrifugo --config=/var/www/centrifugo/config.json
I leave it here in case this could help anyone
Anyway if someone knows how to translate the balancer configuration on the virtual host, that part it's still missing, thanks

Dotnet Core on Ubuntu and Apache configuration

I am trying to host a simple Hello World on Ubuntu 16.04.5 LTS.
So far I have built the .NetCore application as a Self Contained Deployment release and ftp'd to my server inside /var/www/CoreWebsite
I have configured an existing Apache configuration inside /etc/apache2/sites-enabled/mySite with the following:
<VirtualHost *:80>
ServerName www.myWebSite.co.uk
ServerAlias myWebsite.co.uk
DocumentRoot /var/www/CoreWebsite
ProxyPass / http://localhost:4000
ProxyPassReverse / http://localhost:4000
#Other directives here
# Options -Indexes
</VirtualHost>
Inside my Program.cs I have the following:
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("http://*:4000")
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
I have restarted the Apache Service and all I am getting when i navigate to myWebsite.co.uk is a 503 Service unavailable. I am not sure if I have to enable something for kesteral to be running, or enable a pass through?
This is a fresh installation and I haven't activated, or installed anything other than copying the files to the server...

Resources