Apache load balancing with RewriteCond not working? - apache

I have installed the apache httpd service and tried to set up load balancing.
I want to rewrite requests on a specific condition - when the Host header is "images.server.com", I want to rewrite the request, adding "/images/" to the URI and then proxy it to my upstream server.
The mod_proxy module comes perfectly for the task: https://httpd.apache.org/docs/current/rewrite/proxy.html
Well, not so great - my setup is the following:
<Proxy balancer://mycluster>
BalancerMember http://xxx.xx.xx.xx:8080
</Proxy>
ProxyPreserveHost On
RewriteEngine On
RewriteCond %{HTTP_HOST} ="images.server.com"
RewriteRule "/(.*)" "/images/%1" [P]
ProxyPass /images balancer://mycluster/images
and it is not working :(
Please help me figure out where is the flaw in this configuration.
P.S. I have loaded the modules:
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so

Don't use both the 'P' flag and ProxyPass. If you're going to use the 'P' flag, use balancer://... in the substitution and drop ProxyPass entirely.

Related

How do I setup websockets on apache using this tutorial, with just built in apache modules?

I'm trying to use these instructions to setup a websockets connection on my localhost apache webserver and it's not working.
I have the mod_proxy_wstunnel and mod_proxy modules turned on so I should have the capability of running websockets on localhost. Nowadays Apache webserver has websockets support built in. Gone of the days of installing third party websockets apache modules like Rachet.
I get this error after following the instructions in the above question.
Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
WebSocket connection to 'ws://socket.localhost/' failed:
I'm using apache webserver, not litespeed, lighttpd, nginx or IIS.
By the way I'm using Uniform Server.
My first attempt (in case someone comments for me to show my work)
Make sure that the following apache modules are turned on
mod_proxy_wstunnel
mod_proxy_modules
Edit the already existing file called httpd.conf to then insert this into it. Make sure you edit the correct file if you have duplicate file names for different apache versions
<VirtualHost *:80>
ServerName socket.localhost
ProxyRequests Off
ProxyPass "/ws2/" "ws://localhost:8546/"
ProxyPass "/wss2/" "wss://localhost:8546/"
</VirtualHost>
Test the websocket using this HTML page with inline javascript
<script type="text/javascript">
var socket = new WebSocket('ws://socket.localhost');
socket.send('Test');
</script>
Below is an example that I use for GraphQL subscription via websocket.
IP & Port are meant to be replaced by your configuration.
Make sure you have these modules installed:
proxy_module (shared)
proxy_http_module (shared)
proxy_wstunnel_module (shared)
rewrite_module (shared)
Site Config:
<VirtualHost *:443>
ServerName something.com
ServerAdmin web#localhost
DocumentRoot /var/www/html
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/subscription [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://ip:port/$1 [P,L]
ProxyPass "/subscriptions" "ws://ip:port/subscriptions"
ProxyPassReverse "/subscriptions" "ws://ip:port/subscriptions"
ProxyPass "/" "http://ip:port/"
ProxyPassReverse "/" "http://ip:port/"
</VirtualHost>
/Subscription
Is my websocket endpoint. Yours might differ.

Session Keeps Getting Recreated

i have a single payara instance. have been able to configure request forwarding from my apache web server to my payara. however upon every reload of a page using the actual domain url i have, the session gets recreated hence losing any attributes stored in the session from the previous request. However, same does not occur when i access my application via the ipaddress instead of the domain name
i am using a centos8 vps. didnt find mod_session as part of the modules in the /etc/httpd/modules folders so i installed using
yum install mod_sessions
and after running successfully checked and they were now in the modules folder. so i then edited the /etc/httpd/conf.modules.d/01-session.conf with the following lines
**LoadModule session_module modules/mod_session.so
LoadModule request_module modules/mod_request.so
LoadModule session_cookie_module modules/mod_session_cookie.so
LoadModule session_dbd_module modules/mod_session_dbd.so
LoadModule auth_form_module modules/mod_auth_form.so
LoadModule session_crypto_module modules/mod_session_crypto.so**
and then restarted the apache httpd server.
however, still doesn't work. visiting the webpage via the domain name recreates a new session at every request.
this is my current virtual host file setting
<VirtualHost *:80>
ServerName www.someapp.com
ServerAlias someapp.com
Session On
SessionEnv On
SessionCookieName session path=/
ProxyPreserveHost On
ProxyPass / http://localhost:8080/someapp/
ProxyPassReverse / http://localhost:8080/someapp/
RewriteEngine On
RewriteRule "^/someapp/?$" "home.jsp" [NC]
#RewriteRule ^/someapp/(.*)$ /$1 [NC]
</VirtualHost>
NOTE: someapp is not the name of the real app. just using that name in this example but u get the idea
i really need help. am unable to make login pages on my website work because once i enter the login details and after validation the user is set in the session, upon redirecting or making another request, new session gets created and i lose the user and am back to the login screen again of my application. please i need help
So for anyone facing this same problem as i did, the answer was to introduce the ProxyPassReverseCookiePath in the VirtualHost config file in the apache httpd conf files such that now your VirtualHost looks something like this:
<VirtualHost *:80>
ServerName www.someapp.com
ServerAlias someapp.com
Session On
SessionEnv On
SessionCookieName session path=/
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:8080/someapp/
ProxyPassReverse / http://localhost:8080/someapp/
ProxyPassReverseCookiePath / http://localhost:8080/someapp/
</VirtualHost>
Also, major thank you to the similar issue solved on How to configure apache-vhost.conf file for getting Session value from Java

Apache reverse proxy for websockets

I'm using Apache on my server to proxy traffic on port 80 and 443 out to separate VM's running different websites and services. I'm having trouble setting up a proxy for MeshCentral which requires websockets. I'm using Debian 10 with Apache 2.4.38.
I can load MeshCentral, but once I login it tries to use websockets and I get the following error;
Firefox can’t establish a connection to the server at wss://example.com/control.ashx?auth=Uu7PBFNsswzzWoQaVNPH2N3ZwkWbx7DSsljaaY8cxthO5fcPVSz#sqLbGzyOpvxTxvfmV7WgwLdRklqLNYC5KQTjrZPCYDcNDvJ0AY7V8DGdUk68jK3sPfnc$Sl7rvhaQwR1xBukiZ8=. meshcentral.js:27:21
I've added the wstunnel proxy
a2enmod proxy_wstunnel
And setup HTTP and HTTPS proxies which work fine
/etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
ProxyPass "/" "http://192.168.200.11/"
ProxyPassReverse "/" "http://example.com/"
</VirtualHost>
/etc/apache2/sites-enabled/000-default-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
RewriteEngine on
RewriteCond ${HTTP:UPGRADE} websocket [NC]
RewriteCond ${HTTP:CONNECTION} upgrade [NC]
RewriteRule /(.*) "wss://example.com/$1" [P]
ProxyPreserveHost On
ProxyPass "/" "https://192.168.200.11/"
ProxyPassReverse "/" "https://example.com/"
SSLProxyEngine On
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/mydomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.com/privkey.pem
</VirtualHost>
</IfModule>
I've restarted apache before I tried loading the page in firefox and also tried google-chrome, same error.
You can try with:
Ubuntu
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
Centos
Open the module configuration file for proxies.
sudo vi /etc/httpd/conf.modules.d/00-proxy.conf
All modules related to proxying are listed in this configuration file. Verify that the following lines exist and are uncommented.
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel modules/mod_proxy_wstunnel.so
If you made any changes to the file, save them now.
Restart Apache Web Server to apply your changes.
sudo systemctl restart httpd
Configuration:
<VirtualHost *:443>
ServerName ws.serverlab.ca
RewriteEngine on
RewriteCond ${HTTP:Upgrade} websocket [NC]
RewriteCond ${HTTP:Connection} upgrade [NC]
RewriteRule .* "wss:/localhost:3000/$1" [P,L]
<Proxy balancer://backend-cluster>
BalancerMember http://server01:3000
BalancerMember http://server02:3000
BalancerMember http://server03:3000
</Proxy>
ProxyPass / balancer://backend-cluster/
ProxyPassReverse / balancer://backend-cluster/
ProxyRequests off
</VirtualHost>
ServerName ws.serverlab.ca
The hostname of the virtual web host that will handle the WebSocket connections.
RewriteEngine on
Used to set the status of the RewriteEngine to either on or off. To support WebSockets it must be turned on.
RewriteCond ${HTTP:Upgrade} websocket [NC]
A condition that must be matched in order for a request to be processed by the RewriteRule.
RewriteCond ${HTTP:Connection} upgrade [NC]
To something
RewriteRule . “wss:/ws-backend%{REQUEST_URI}” [P]*
Rewrite all incoming requests to use the wss protocol, and replace the destination hostname to that of a backend service.
Documentation from: How to Reverse Proxy Websockets with Apache 2.4

Apache Redirect Request From Domain + Path

I am using apache in front of tomcat so I can redirect requests from the domain to the tomcat url using mod_proxy. I've run into an issue on the server where when using a subdomain it wants to go back to the base domain. Is there any way to redirect all requests from example.com/foo to foo.example.com?
<VirtualHost *:80>
ServerName example.com/app
ProxyPreserveHost Off
ProxyPass / http://app.example.com:8080/AppName/
ProxyPassReverse / http://app.example.com:8080/AppName/
</VirtualHost>
The example above is not working. I presume that is because I cannot include a path in the servername.
Here is my working version of the tag based on the accepted answer.
<VirtualHost *:80>
ServerName example.com/app
ProxyPreserveHost Off
ProxyPass / http://app.example.com:8080/AppName/
ProxyPassReverse / http://app.example.com:8080/AppName/
# Rewrite all request from example.com/foo to foo.example.com
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^/foo/?(.*) http://foo.example.com/$1 [R,L]
</VirtualHost>
Speaking strictly to the last statement in your original post, "Is there any way to redirect all requests from example.com/foo to foo.example.com".
You can use a rewrite to accomplish this. For example:
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^/foo/?(.*) http://foo.example.com/$1 [R,L]
This assumes that your rewrite module is loaded and enabled:
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
You could use mod_rewrite within apache. Ensure it is enabled, as root:
a2enmod rewrite
That will confirm it is has been enabled or already is. If it has been enabled you'll need a restart of Apache.
Then in your root of your virtualhost create/edit .htaccess file and add the line:
Redirect /foo/ http://foo.example.com/
Depending on your specific directory permissions you may need to allow overrides for the directory
<Directory /your/path/here>
AllowOverride All
</Directory>
HTH

jk_mod and apache rewrite

Is it possible to combine rewrite rules with jk_mod with server side forward?
I have a simple configuration
RewriteEngine On
RewriteRule ^/$ /myapp [R]
JkMount /* worker_1
This works great when using the redirect flag but fails to run without it. What I want to achieve is a server side forward so the user's browser bar doesn't notice the rewrite.
Thank you.
Give a try to mod_proxy_http, You need to enable mod_proxy and mod_proxy_http:
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
Then in your VirtualHost section:
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /css !
ProxyPass /img !
ProxyPass /js !
ProxyPass / http://localhost:8080/myapp/
ProxyPassReverse / http://localhost:8080/myapp/
Note: the ProxyPass /xxx ! are not needed from your question. I just wanted to show how to exclude some URI from being 'translated'