Web Socket behind proxy - websocket

I have Spring Boot app with WebSocket running behind Apache 2. When trying connect I am getting the following error:
Server Log:
Handshake failed due to invalid Upgrade header: null
Client Log:
Here is the Apache 2 config:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin tom_marik#hotmail.com
ServerName www.languageexchange.eu
ProxyPass "/ws2/" "ws://www.languageexchange.eu:92/"
ProxyPass "/wss2/" "wss://www.languageexchange.eu:92/"
ProxyPass / http://31.31.74.54:92/
ProxyPassReverse / http://31.31.74.54:92/
ProxyPassReverseCookiePath / /
ErrorLog /var/log/apache2/languageexchange.log
LogLevel warn
RewriteEngine on
[END,QSA,R=permanent]
SSLCertificateFile /etc/letsencrypt/live/languageexchange.eu/cert.pem
SSLCertificateKeyFile
/etc/letsencrypt/live/languageexchange.eu/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile
/etc/letsencrypt/live/languageexchange.eu/chain.pem
</VirtualHost>
</IfModule>
Thanks for any help!

You need to have mod_proxy_wstunnel installed (mod_proxy and mod_ssl as well). Then in your Apache's configuration:
ProxyPass /ws2 ws://languageexchange.eu:92 keepalive=On
ProxyPassReverse /ws2 ws://languageexchange.eu:92
ProxyPass /wss2 wss://languageexchange.eu:92 keepalive=On
ProxyPassReverse /wss2 wss://languageexchange.eu:92
If this is a single machine it may be better to set 127.0.0.1 instead of languageexchange.eu, so:
ProxyPass /ws2 ws://127.0.0.1:92 keepalive=On
ProxyPassReverse /ws2 ws://127.0.0.1:92
ProxyPass /wss2 wss://127.0.0.1:92 keepalive=On
ProxyPassReverse /wss2 wss://127.0.0.1:92

Related

Pentaho j_spring_security_check mixed content. HTTPS to HTTP

I have installed Pentaho (9.x) on Tomcat 8.5 and OpenJDK 1.8 as required.
In front of it there is Apache 2.4 with mod_proxy_http.
My website is served with HTTPS and I have these Proxy rules:
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPass "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
ProxyPassReverse "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
ProxyPass "/pentaho/Login" "http://tomcat_host_ip:8080/pentaho/Login"
ProxyPassReverse "/pentaho/Login" "http://tomcat_host_ip:8080/pentaho/Login"
When I try to log in a get an error during the POST:
https://pentaho.mywebsite.org/pentaho/j_spring_security_check
The application try to responde with HTTP protocol instead HTTPS.
In the request header I have the correct Referer and Origin:
Origin: https://pentaho.mywebsite.org
Referer: https://pentaho.mywebsite.org/pentaho/Login
But the response header reply with HTTP and NOT https:
Location http://pentaho.mywebsite.org/pentaho/
I solved the problem just adding proxyPort="443" and scheme="https" to my http connector in Tomcat.
The rule
RequestHeader set X-Forwarded-Proto "https"
on Apache was unusefull. This is my correct Apache configuration
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPass "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
ProxyPassReverse "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
And this is my Tomcat HTTP connector
<Connector URIEncoding="UTF-8"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
proxyPort="443"
scheme="https"
redirectPort="8443"
relaxedPathChars="[]|"
relaxedQueryChars="^{}[]|&"
maxHttpHeaderSize="65536"
/>
Servlet applications use the scheme, serverName and serverPort properties of a ServletRequest to generate hyperlinks. Usually Tomcat gets the latter two from the Host request header, while scheme depends on the connector.
If you use a reverse proxy, the above logic may not be enough. You have two solution:
Setting scheme statically
In your case the proxy uses HTTPS, while Tomcat uses HTTP, so you must override the scheme and secure properties:
<Connector
port="8080"
scheme="https"
secure="true"
...
while the Apache HTTP Server configuration can be shortened to:
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
Remark that in your answer you didn't set the secure attribute: this attribute decides whether the transport is confidential. If you don't set it to true, Tomcat will automatically redirect the browser to redirectPort whenever the application asks for a confidential transport (cf. Securing Web Applications).
This solution only works correctly, if your proxy forwards only HTTPS requests to Tomcat.
Setting scheme dynamically
If you forward both HTTP and HTTPS requests to Tomcat, the server needs a way to distinguish between them. Therefore you need to add a RemoteIpValve to your Tomcat configuration:
<Valve className="org.apache.catalina.valves.RemoteIpValve" />
<Connector
port="8080"
redirectPort="443"
...
and ask Apache HTTP Server to add an X-Forwarded-Proto header:
RequestHeader set X-Forwarded-Proto "expr=%{REQUEST_SCHEME}"
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
This solution has also the advantage to set the client's remoteHost and remoteAddr instead of those of the proxy.

How to write configuration Apache load balancer for many Spring-Boot?

We want to use Apache load balance to spread the load over several servers. We plan to do many http://load_balancer:port/app_name redirects on Apache LB e.g:
http://load_balancer:port/app1 ---> Apache LB ---> http://server1:port1, http://server2:port1
http://load_balancer:port/app2 ---> Apache LB ---> http://server1:port2, http://server2:port2
....
For Apache LB configuration file as below, when we use http://load_balancer:port in web browser then Apache LB works as expected.
How to rewrite the configuration so that you can enter http://load_balancer:port/app in web browser?
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy "balancer://mycluster">
BalancerMember "http://server1:port" route=1 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
BalancerMember "http://server2:port" route=2 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
ProxySet stickysession=ROUTEID
</Proxy>
<Proxy "balancer://myws">
BalancerMember "ws://http://server1:port" route=1 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
BalancerMember "ws://http://server2:port" route=2 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
ProxySet stickysession=ROUTEID
</Proxy>
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) balancer://myws/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) balancer://mycluster/$1 [P,L]
Second configuration
We used the hint as below for the proxy flag. Apache LoadBalancer worked fine for "http://load_balancer:port/". My configuration file:
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid scolonpathdelim=On
<Proxy "balancer://mycluster">
BalancerMember "http://server1:8727" route=1
BalancerMember "http://server2:8193" route=2
</Proxy>
When we changed the configuration to ProxyPass "/test" to refer to "http://load_balancer:port/test" from the web browser, there were errors (404) in the access.log file:
GET /test/ HTTP/1.1 200 2375
GET /static/css/app.77ac3251.css HTTP/1.1 404 196
...
You can use apache proxy pass instead of a rewriterule with proxy flag. You can find all the detail about the configuration on the official documentation: https://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html
We wrote the configuration as below and it works as expected:
<Proxy balancer://test.cl>
Header add Set-Cookie "test.ROUTEID=ROUTE.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
BalancerMember http://server1:8727 route=test_00 keepalive=On connectiontimeout=5 retry=180
BalancerMember http://server2:9393 route=test_10 keepalive=On connectiontimeout=5 retry=180
ProxySet lbmethod=bybusyness stickysession=ROUTEID
</Proxy>
<Location /test>
ProxyPreserveHost On
ProxyPass balancer://test.cl
ProxyPassReverse balancer://test.cl
</Location>

How to enable login functionality for elastic search & Kibana of Bitnami ELK Stack solution?

Below I provided both kibana vhost file. what changes I have to make so that kibana dashboard is username & password protected.
kibana-https-vhost.conf
<VirtualHost 127.0.0.1:443 _default_:443>
ServerAlias *
SSLCertificateFile "/opt/bitnami/apache/conf/bitnami/certs/server.crt"
SSLCertificateKeyFile "/opt/bitnami/apache/conf/bitnami/certs/server.key"
ProxyPass /elasticsearch http://127.0.0.1:9200
ProxyPassReverse /elasticsearch http://127.0.0.1:9200
ProxyPass / http://127.0.0.1:5601/
ProxyPassReverse / http://127.0.0.1:5601/
# HTTP Basic authentication layer
<Location />
AuthType Basic
AuthName "Introduce your ELK credentials. If you have problems,.."
AuthBasicProvider file
AuthUserFile /opt/bitnami/kibana/conf/password
Require user user
</Location>
</VirtualHost>
kibana-vhost.conf
<VirtualHost 127.0.0.1:80 _default_:80>
ServerAlias *
ProxyPass /elasticsearch http://127.0.0.1:9200
ProxyPassReverse /elasticsearch http://127.0.0.1:9200
ProxyPass / http://127.0.0.1:5601/
ProxyPassReverse / http://127.0.0.1:5601/
# HTTP Basic authentication layer
<Location />
AuthType Basic
AuthName "Introduce your ELK credentials. If you have problems, .."
AuthBasicProvider file
AuthUserFile /opt/bitnami/kibana/conf/password
Require user user
</Location>
</VirtualHost>

How to configure Apache reverse proxy domain url to specific url on localhost

I am stuck with an issue i have with configuring apache reverse proxy server.
I want to use an url eq.: https://software.testsite.net and my reverse proxy should be configured using http://localhost:82/customapp.
The problem currently when i navigate to https://www.testsite.net it is replaced with http://localhost:82/customapp.
How do i go about configuring this?
My configuration:
<VirtualHost *:443>
SSLEngine on
ServerName software.testsite.net
SSLProxyEngine On
SSLCertificateFile "${SRVROOT}/certs/testsite.crt"
SSLCertificateKeyFile "${SRVROOT}/certs/testsite.key"
SSLCertificateChainFile "${SRVROOT}/certs/testsite.ca-bundle"
RequestHeader edit Destination ^https http early
<Location />
RedirectMatch ^/$ https://localhost:82/customapp
ProxyPass http://localhost:82/customapp
ProxyPassReverse http://localhost:82/customapp
</Location>
</virtualhost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyVia on
RewriteEngine on
ProxyRequests Off
SSLProxyEngine On
SSLCertificateFile "${SRVROOT}/certs/testsite.crt"
SSLCertificateKeyFile "${SRVROOT}/certs/testsite.key"
SSLCertificateChainFile "${SRVROOT}/certs/testsite.ca-bundle"
# used for enforcing http to https
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{SERVER_NAME}$1 [R,L]
ServerName software.testsite.net
<Location />
ProxyPass http://localhost:82/customapp
ProxyPassReverse http://localhost:82/customapp
</Location>
</VirtualHost>
I finally got it working. Not sure if this is the way it is supposed to be done though.
<VirtualHost *:80>
ServerName software.testsite.net
DocumentRoot "${SRVROOT}/htdocs/software"
DirectoryIndex index.html
ProxyPreserveHost On
ProxyVia on
RewriteEngine on
ProxyRequests Off
# used for enforcing http to https
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{SERVER_NAME}$1 [R,L]
SSLProxyEngine On
SSLCertificateFile "${SRVROOT}/certs/testsite.crt"
SSLCertificateKeyFile "${SRVROOT}/certs/testsite.key"
SSLCertificateChainFile "${SRVROOT}/certs/testsite.ca-bundle"
<Location /customapp>
ProxyPass http://localhost:82/customapp
ProxyPassReverse http://localhost:82/customapp
</Location>
</VirtualHost>
<VirtualHost *:443>
ServerName software.testsite.net
DocumentRoot "${SRVROOT}/htdocs/software"
DirectoryIndex index.html
RequestHeader edit Destination ^https http early
SSLEngine on
SSLProxyEngine On
SSLCertificateFile "${SRVROOT}/certs/testsite.crt"
SSLCertificateKeyFile "${SRVROOT}/certs/testsite.key"
SSLCertificateChainFile "${SRVROOT}/certs/testsite.ca-bundle"
<Location /customapp>
RedirectMatch ^/$ https://localhost:82/customapp
ProxyPass http://localhost:82/customapp
ProxyPassReverse http://localhost:82/customapp
</Location>
</virtualhost>
<!DOCTYPE html>
<html>
<head>
<title>HTML Meta Tag</title>
<meta http-equiv = "refresh" content = "1; url =http://software.testsite.net/customapp"/>
</head>
<body>
<p>Redirecting...</p>
</body>
</html>

Access forbidden error 403 XAMPP. I've tried other's solutions

Before I get started I have been doing my research in regards to why I'm getting this error and yet whatever I change I still end up with the same error page. This may have to do with the fact that the answers to this previously solved question were answered years ago on older versions of XAMPP.
Error Page:
"Access forbidden!
You don't have permission to access the requested directory. There is either no index document or the directory is read-protected.
If you think this is a server error, please contact the webmaster.
Error 403
localhost
Apache/2.4.18 (Win32) OpenSSL/1.0.2e PHP/7.0.8"
Below is the code to my httpd-xampp.conf file:
#
# XAMPP settings
#
<IfModule env_module>
SetEnv MIBDIRS "C:/xampp/php/extras/mibs"
SetEnv MYSQL_HOME "\\xampp\\mysql\\bin"
SetEnv OPENSSL_CONF "C:/xampp/apache/bin/openssl.cnf"
SetEnv PHP_PEAR_SYSCONF_DIR "\\xampp\\php"
SetEnv PHPRC "\\xampp\\php"
SetEnv TMP "\\xampp\\tmp"
</IfModule>
#
# PHP-Module setup
#
LoadFile "C:/xampp/php/php7ts.dll"
LoadFile "C:/xampp/php/libpq.dll"
LoadModule php7_module "C:/xampp/php/php7apache2_4.dll"
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
#
# PHP-CGI setup
#
#<FilesMatch "\.php$">
# SetHandler application/x-httpd-php-cgi
#</FilesMatch>
#<IfModule actions_module>
# Action application/x-httpd-php-cgi "/php-cgi/php-cgi.exe"
#</IfModule>
<IfModule php7_module>
PHPINIDir "C:/xampp/php"
</IfModule>
<IfModule mime_module>
AddType text/html .php .phps
</IfModule>
ScriptAlias /php-cgi/ "C:/xampp/php/"
<Directory "C:/xampp/php">
AllowOverride None
Options None
Require all denied
<Files "php-cgi.exe">
Require all granted
</Files>
</Directory>
<Directory "C:/xampp/cgi-bin">
<FilesMatch "\.php$">
SetHandler cgi-script
</FilesMatch>
<FilesMatch "\.phps$">
SetHandler None
</FilesMatch>
</Directory>
<Directory "C:/xampp/htdocs/xampp">
<IfModule php7_module>
<Files "status.php">
php_admin_flag safe_mode off
</Files>
</IfModule>
AllowOverride AuthConfig
</Directory>
<IfModule alias_module>
Alias /licenses "C:/xampp/licenses/"
<Directory "C:/xampp/licenses">
Options +Indexes
<IfModule autoindex_color_module>
DirectoryIndexTextColor "#000000"
DirectoryIndexBGColor "#f8e8a0"
DirectoryIndexLinkColor "#bb3902"
DirectoryIndexVLinkColor "#bb3902"
DirectoryIndexALinkColor "#bb3902"
</IfModule>
Require local
ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
</Directory>
Alias /phpmyadmin "C:/xampp/phpMyAdmin/"
<Directory "C:/xampp/phpMyAdmin">
AllowOverride AuthConfig
Require local
ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
</Directory>
Alias /webalizer "C:/xampp/webalizer/"
<Directory "C:/xampp/webalizer">
<IfModule php7_module>
<Files "webalizer.php">
php_admin_flag safe_mode off
</Files>
</IfModule>
AllowOverride AuthConfig
Require local
ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
</Directory>
</IfModule>``

Resources