Attempting to reconnect to the server 1 of 8 - apache

Problem with Blazor Test application. I run this app. over Apache server with proxy:
<VirtualHost *:*>
RequestHeader set \"X-Forwarded-Proto\" expr=%{REQUEST_SCHEME}
</VirtualHost>
Listen 192.168.0.190:44366
# for ASP.NET app TestBlazor
<VirtualHost 192.168.0.190:44366>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:44366/
ProxyPassReverse / http://127.0.0.1:44366/
ServerName 192.168.0.190:44366
# ServerAlias 192.168.0.190:44366
</VirtualHost>
However, a message appears every minute: Attempting to reconnect to the server. Where can be problem ?
Firefox console:

I found the answer here:WebSockets and Apache proxy : how to configure mod_proxy_wstunnel?
Virtual host must be configured as follows:
<VirtualHost *:*>
RequestHeader set \"X-Forwarded-Proto\" expr=%{REQUEST_SCHEME}
</VirtualHost>
Listen 192.168.0.190:44366
# for ASP.NET app TestBlazor
<VirtualHost 192.168.0.190:44366>
ServerName 192.168.0.190:44366
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:44366/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:44366/$1 [P,L]
ProxyPass / http://localhost:44366/
ProxyPassReverse / http://localhost:44366/
</VirtualHost>

Related

Websockets not working while running Portainer with Httpd proxying

I've set up the Portainer UI as a docker container, and it's working great if I connect my browser to port 9000 (as in http://foo.bar.com:9000). I can navigate around the UI and open up container consoles (which use websockets) without a problem.
But, what I need to do i connect with SSL (as in https://foo.bar.com).
I set up an httpd container on the same machine, and gave it the following configuration file:
<VirtualHost *:443>
ServerName foo.bar.com
ProxyPass / http://foo.bar.com:9000/
ProxyPassReverse / http://foo.bar.com:9000/
RequestHeader set X-Forwarded-Proto "https"
<Location /api/websocket/>
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /api/websocket/(.*) ws://foo.bar.com:9000/api/websocket/$1 [P]
</Location>
## SSL directives
SSLEngine on
SSLCertificateFile "/usr/local/apache2/conf/server.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"
## Logging
ServerSignature Off
ErrorLog "logs/error_ssl.log"
CustomLog "logs/access_ssl.log" common
</VirtualHost>
Both httpd and portainer are being brought up by separate docker-compose.yml files.
Now, the Portainer web pages still come up just fine, but the consoles for the containers won't work. Somehow, my websocket configuration above is broken. Any ideas on what I might be doing wrong?
After hours of playing with it, I finally got this to work and wanted to share. First, at least in httpd 2.4, you need to explicitly load mod_proxy_wstunnel.so so make sure and put a LoadModule in. Until you do that, nothing will work.
Here is the httpd configuration that was successful:
<VirtualHost *:443>
ServerName foo.bar.com
ProxyPreserveHost on
ProxyPreserveHost On
ProxyRequests Off
# allow for upgrading to websockets
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule ^/?(.*) ws://foo.bar.com:9000/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule ^/(.*) http://foo.bar.com:9000/$1 [P,L]
ProxyPass "/" "http://foo.bar.com:9000/"
ProxyPassReverse "/" "http://foo.bar.com:9000/"
## SSL directives
SSLEngine on
SSLCertificateFile "/usr/local/apache2/conf/server.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"
## Logging
ServerSignature Off
ErrorLog "logs/error_ssl.log"
CustomLog "logs/access_ssl.log" common
</VirtualHost>
Thanks a lot - saved me lot of trouble setting this up in Apache. I'm using it in local network only so I don't care much about https and certs so I've modified it bit to go through http
<VirtualHost *:80>
ServerName foo.bar.com
ServerAlias foo.bar.alias.com
ProxyPreserveHost On
ProxyRequests Off
# allow for upgrading to websockets
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule ^/?(.*) ws://localhost:9000/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule ^/(.*) http://localhost:9000/$1 [P,L]
ProxyPass "/" "http://localhost:9000/"
ProxyPassReverse "/" "http://localhost:9000/"
# Logging
ErrorLog ${APACHE_LOG_DIR}/portainer_error.log
CustomLog ${APACHE_LOG_DIR}/portainer_access.log combined
</VirtualHost>

Route mqtt and websocket traffic through apache2

I have a emqx broker setup on Ubuntu EC2.
When I try to connect to emqx through websocket with IP address, it works fine.
But when I use subdomain, the connection fails.
My Apache Config is
<VirtualHost *:80>
ServerName subdomain.example.com
ServerAlias subdomain.example.com
ServerAdmin admin#domain.in
RewriteEngine On
#RewriteCond %{REQUEST_URI} ^/socket.io [NC]
#RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule ^/mqtt/(.*) ws://localhost:8083/mqtt/$1 [P,L]
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://localhost:8083/
ProxyPassReverse / http://localhost:8083/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Apache access Logs
I changed the log level of apache to 'debug' and these are the error logs. Looks like it is trying to find the /mqtt folder.
I have already enabled mode "proxy_wstunnel.load". How can I connect to mqtt and ws using subdomain?
Add a ServerAlias directive under ServerName
Example:
ServerName domain.com
ServerAlias subdomain.domain.com
Try adding this too
ProxyPass "/" "http://127.0.0.1:8083/mqtt"
ProxyPassReverse "/" "http://127.0.0.1:8083/mqtt"
If you're are not sure if the broker is using socket.io, then remove this line:
#RewriteCond %{REQUEST_URI} ^/socket.io

ASP.NET Core 3 Blazor: Run on localhost of server ok, but run outside server error: Error during WebSocket handshake: Unexpected response code: 200

I am using .NET Core 3.0.0 , Blazor server-side, Visual Studio 2019, Windows Server 2016. I run on server ok, but connection from outside server is error.
I use Apache HTTP Web server 2.4 virtual host (http://httpd.apache.org/docs/2.4/vhosts/ ), file httpd-vhosts.conf
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ServerName demo.example.com
ErrorLog ${APACHE_LOG_DIR}webapp1-error.log
CustomLog ${APACHE_LOG_DIR}webapp1-access.log common
</VirtualHost>
In httpd.conf , enable module: proxy , proxy_httpd , proxy_wstunnel and
<VirtualHost *:80>
ServerName demo.example.com
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/demo.example.com [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P,L]
ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/
</VirtualHost>
this error
blazor.server.js:1 WebSocket connection to
'ws://demo.xxxx.xx/_blazor?id=LZk17pmIejWGHLkhN3HFmA' failed: Error
during WebSocket handshake: Unexpected response code: 200
Seems others had problems with proxying the web socket connection. Found a potential solution for you here: https://github.com/aspnet/Blazor/issues/1882
<VirtualHost *:80>
ServerName www.domain.com
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 /.log
CustomLog /.log common

"Unexpected token H in JSON at position 0" SignalR Core and Kestrel on Apache Web Server

I'm currently running an apache2 webserver on Ubuntu. This web server is hosting a Vue.js web app that connects to a .Net Core app (also on the same linux server) with SignalR to create a websocket.
The .Net Core app is ran using Kestrel. Below is the apache config to reroute the domain.com/api to the .Net Core app running on port 5000.
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
<VirtualHost _default_:443>
DocumentRoot /var/www/example.com/dist/spa
ServerName www.example.com
ServerAlias example.com
ProxyPreserveHost On
ProxyPass "/api" http://localhost:5000/
ProxyPassReverse "/api" http://localhost:5000/
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P]
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
SSLCertificateFile /etc/apache2/ssl/example_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/example_com.ca-bundle
ErrorLog ${APACHE_LOG_DIR}example-error.log
CustomLog ${APACHE_LOG_DIR}example.log common
</VirtualHost>
When the Vue.js app attempts to create a websocket connection to the example.com/api/mainHub the following error occurs:
Failed to complete negotiation with the server: SyntaxError: Unexpected token H in JSON at position 0
It seems to be sending the request to the correct URL, https://example.com/api/mainHub but fails to establish the connection.
One thing I noticed on the Linux server, is the POST does not include the /api in the path.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 POST http://example.com//mainHub/negotiate text/plain;charset=UTF-8 0
Is this an issue with how my apache2 config is routing the requests to the /api directory?
Edit
I've since changed my apache config to remove the extra / at the end of the localhost:5000 - This allowed the outside connection to reach the correct API path.
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
<VirtualHost _default_:443>
DocumentRoot /var/www/example.com/dist/spa
ServerName www.example.com
ServerAlias example.com
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteRule /(.*) wss://localhost:5000$1 [P]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) https://localhost:5000$1 [P]
ProxyPreserveHost On
ProxyPass "/api" http://localhost:5000
ProxyPassReverse "/api" http://localhost:5000
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
SSLCertificateFile /etc/apache2/ssl/example_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/example_com.ca-bundle
ErrorLog ${APACHE_LOG_DIR}example-error.log
CustomLog ${APACHE_LOG_DIR}example.log common
</VirtualHost>
The issue now seems to be with the secure websocket upgrade. I tried changing the ws upgrade to wss, but something is still wrong. When the client attempts to make the wss connection, the following error occurs:
WebSocket connection to 'wss://example.com/api/mainHub?id=k1-_KxspgAQgIAhKroQBpQ' failed: Error during WebSocket handshake: Unexpected response code: 502
I believe something is wrong with how my virtual host is upgrading the websocket connection with HTTPS.
Error: Failed to start the transport 'WebSockets': null
If your .Net Core app is listening at /api/ on port 5000, then add that to ProxyPass directives:
ProxyPass "/api" http://localhost:5000/api
ProxyPassReverse "/api" http://localhost:5000/api
Edit: Try
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P]
ProxyPreserveHost On
ProxyPass "/api" http://localhost:5000
ProxyPassReverse "/api" http://localhost:5000

Redirect http to https only works after page refresh Apache2

I have installed SSL Certificates on my website and on the example.com everything works fine, meaning that typing example.com redirects correctly to https://example.com. However, I have installed a certificate for a subdomain as well such that the link becomes: subdomain.example.com.
My goal is to have subdomain.example.com redirect to https://subdomain.example.com . This might sound weird but this semi-works meaning that when I first surf to subdomain.example.com it uses the http protocol but when I refresh that same page it switches to https protocol.
This is my VirtualHost conf file (port 80):
<VirtualHost *:80>
ServerName subdomain.example.com
ServerSignature Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Location />
Require all granted
ProxyPassReverse http://127.0.0.1:8181
ProxyPassReverse http://example.com/
</Location>
RewriteEngine on
#Forward all requests to gitlab-workhorse except existing files like error documents
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} ^/uploads/.*
RewriteRule .* http://127.0.0.1:8181%{REQUEST_URI} [P,QSA,NE]
# needed for downloading attachments
DocumentRoot /opt/gitlab/embedded/service/gitlab-rails/public
RewriteCond %{SERVER_NAME} =subdomain.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
#RewriteCond %{SERVER_PORT} !443
#RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/ [R=301,L]
</VirtualHost>
I have removed to non related lines from this sample above. Here is the 443 conf file:
< IfModule mod_ssl.c>
SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)
<VirtualHost *:443>
ServerName subdomain.example.com
ServerSignature Off
< IfModule mod_ssl.c>
SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)
<VirtualHost *:443>
ServerName subdomain.example.com
ServerSignature Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Location />
Require all granted
#Allow forwarding to gitlab-workhorse
ProxyPassReverse http://127.0.0.1:8181
ProxyPassReverse http://domain/
</Location>
RewriteEngine on
#Forward all requests to gitlab-workhorse except existing files like error documents
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} ^/uploads/.*
RewriteRule .* http://127.0.0.1:8181%{REQUEST_URI} [P,QSA,NE]
# needed for downloading attachments
DocumentRoot /opt/gitlab/embedded/service/gitlab-rails/public
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/subexample.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
Header always set Strict-Transport-Security "max-age=31536000"
SSLUseStapling on
Header always set Content-Security-Policy upgrade-insecure-requests
</VirtualHost>
</IfModule>
Worth noting is that I am using certbot.
Hopefully someone can help me.
You say "My goal is to have subdomain.example.com redirect to https://subdomain.example.com".
Then why have all that proxy configuration in your :80 VirtualHost? Simply force the redirection to :443, and let :443 handle the proxy (and other).
So your VirtualHost would become:
<VirtualHost *:80>
ServerName subdomain.example.com
CustomLog logs/subdomain_80_access.log combined
ErrorLog logs/subdomain_80_error.log
RewriteEngine On
RedirectMatch ^/(.*)$ https://subdomain.example.com/$1
</VirtualHost>