How to add a query parameter to apache 2.4.27 ProxyPass? - apache

I want to map multiple customer facing URLs to a single internal end-point, but with a query parameter to to identify each customer.
For example customer enters https://external_host/customer1
I want a reverse proxy to forward it as https://internal_host/app?customer=cust1
I have tried the following:
<Location "/customer1" >
RewriteEngine On
RewriteRule /customer1 /customer1?customer=cust1 [QSA,P]
ProxyPass https://<internal host>/app
ProxyPassreverse https://<internal host>/app
</Location>
<Location "/customer2" >
RewriteEngine On
RewriteRule /customer2 /customer2?customer=cust2 [QSA,P]
ProxyPass https://<internal host>/app
ProxyPassreverse https://<internal host>/app
</Location>
The basic proxy works, in that the request is forwarded to the internal server, but the query parameter is not added.
From all the reading I have done, I feel it should be possible to do what I want, but cannot get it to work.
Any pointers gratefully received.
Regards
Chris

I solved this as follows:
ProxyRequests off
ProxyPass /app http://<internal server>/app
ProxyPassReverse /app http://<internal server>/app
RewriteEngine on
RewriteRule ^/cust1.htm /app?client=cust1.htm [QSA,P]
RewriteRule ^/cust2.htm /app?client=cust2.htm [QSA,P]
Chris

The ProxyPass and ProxyPassReverse from the question config are ignored, because the P in [QSA,P] performs the proxy request.
Some additional cases to add query parameter extraparam=something to the proxied server:
Regular expression and remote server
if you need to use a regular expression in your rule (first wildcard (.*) is replaced by $1):
RewriteEngine on
RewriteRule ^/path/to/hook/to/proxy/(.*) http://example.org/$1?extraparam=something [QSA,P]
If the proxied server uses https, you should add SSLProxyEngine On to the configuration:
RewriteEngine on
SSLProxyEngine on
RewriteRule ^/path/to/hook/to/proxy/(.*) https://example.org/$1?extraparam=something [QSA,P]

Related

Apache HTTP server redirect to port 8085 IF url contains "demo" ELSE redirect to port 8080

I have 2 applications running on port 8080 and 8085. Both has different URL queries/paths and application on port 8085 have keyword demo on all of its URL queries/paths and other doesn't. So it acts as an unique identifier
Can I make any change to /etc/httpd/conf/httpd.conf file so that if the server identifies demo as the keyword then request will reach application on port 8085, if not then request will reach port application on port 8080 ?
If there is a way, please provide sample configuration which goes into httpd.conf file
EDIT 1:
After trying from first 2 of below answers, I couldn't achieve this. I don't know if ProxyPass and ProxyPassReverse are not allowing to achieve this. I tried commenting them, adding them in VirtualHost etc. But did not help.
This is the flow we are expecting:
User will hit URL (without mentioning port) like - https://example.com/demo and this will be routed to app on port 8085 else routed to 8080
May be taking look at my complete httpd.conf might help
Link to my httpd.conf - https://gofile.io/d/tWIHvX
Rewrite Condition if the query string contains a word "demo":
<VirtualHost *:8080>
<Directory /var/www/example/>
Allow From All
RewriteEngine On
RewriteCond %{SERVER_PORT} !^8085$
RewriteCond %{QUERY_STRING} (demo)
RewriteRule ^Demo http://%{HTTP_HOST}:%{SERVER_PORT}/$1 [L,R]
</Directory>
</VirtualHost>
Rewrite condition if the query string does not contain the word "demo":
<VirtualHost *:8085>
<Directory /var/www/example/>
Allow From All
RewriteEngine On
RewriteCond %{SERVER_PORT} !^8080$
RewriteCond %{QUERY_STRING} (!demo)
RewriteRule ^Demo http://%{HTTP_HOST}:%{SERVER_PORT}/$1 [L,R]
</Directory>
</VirtualHost>
if the SERVER_PORT doesn't work, please try the port directly like below:
RewriteRule ^Demo http://%{HTTP_HOST}:8085/$1 [L,R]
Try:
<VirtualHost *:8080>
#some conf
RewriteCond %{REQUEST_URI} demo [OR]
RewriteCond %{QUERY_STRING} demo
RewriteRule ^ http://%{HTTP_HOST}:8085%{REQUEST_URI} [QSA,L]
#some more conf
</VirtualHost>
OR
<VirtualHost *:8085>
#some conf
RewriteCond %{REQUEST_URI} !demo
RewriteCond %{QUERY_STRING} !demo
RewriteRule ^ http://%{HTTP_HOST}:8080%{REQUEST_URI} [QSA,L]
#some more conf
</VirtualHost>
Note: self answer after being able to achieve this
Achieved this using LocationMatch directive easily. Below is the configuration.
As this is regex dependent you can change to check conditions like ends with, starts with, contains and etc. And both the below LocationMatch conditions are in my httpd.conf
1.If URL like 192.168.1.113/demo then go to 8085
<LocationMatch "^/(demo)(.*)$">
RewriteEngine on
ProxyPass http://localhost:8085/ nocanon
ProxyPassReverse http://localhost:8085/
</LocationMatch>
2.If URL not like 192.168.1.113/demo then go to 8080
<LocationMatch "^/((?!demo).)*$">
RewriteEngine on
ProxyPass http://localhost:8080/ nocanon
ProxyPassReverse http://localhost:8080/
</LocationMatch>

Pass Multiple Parameters From Redirect URL In Apache Proxy Reverse

I'm running an app that utilizes laravel-echo-server. So for me to run it on my production server over https I need to use apache proxy reverse to redirect my /tools/socket.io/ urls to http://localhost:6001.
While that is working fine I keep getting this error Cannot Post / because I need to pass along the params from my domain url to my reverse proxy url.
Here is my apache config:
ProxyPreserveHost On
ProxyRequests off
ProxyPass /tools/socket.io/ http://localhost:6001/
ProxyPassReverse /tools/socket.io/ http://localhost:6001/
I came across this post stack overflow but the implementation didn't work for me.
So this are the parameters I need to pass and their values are dynamic EIO transport t. and my url is like
https://exampledomain.com/tools/socket.io/?EIO=3&transport=polling&t=Ml8lZDJ
Here's my apaxhe config within my SSL virtualhost for my domain:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:6001/$1 [P,L]
ProxyPass /socket.io http://localhost:6001/socket.io
ProxyPassReverse /socket.io http://localhost:6001/socket.io

Apache - Proxy external files to download

Consider this:
we have an external server for files that can be downloaded
our website (plone based) is the interface for downloading them and we try to hide the direct links as much as possible
jquery.fileDownload plugin needs a cookie set on file on download
I'm trying to set our Apache configuration to replace links like this:
original: data-files-example.com/folder/subfolder/file.zip
replaced: our-website-example.com/_downloads/folder/subfolder/file.zip
So, the missing part in my case is: how to set Apache to work like this?
I'm trying:
NameVirtualHost *:80
<VirtualHost :80>
ServerAdmin email#our-website-example.com
ServerName our-website-example.com
RewriteEngine On
RewriteRule "^/_downloads(.)$" "https://data-files-example.com/$1" [P]
RewriteCond %{REQUEST_METHOD} ^(PUT|DELETE|PROPFIND|OPTIONS|TRACE|PROPFIND|PROPPATCH|MKCOL|COPY|MOVE|LOCK|UNLOCK)$
RewriteRule .* - [F,L]
RewriteRule ^/(.*) http://127.0.0.1:/VirtualHostBase/http/data-files-example.com:80/my_plone_website/VirtualHostRoot/$1 [L,P]
</VirtualHost>
I receive 503 Service Unavailable.
How to fix this?
Try a reverse proxy. Just make sure that mod_proxy and mod_proxy_http are enabled in your Apache configuration and that your proxy rule is set before the VirtualHostBase rule for Plone, if the pattern is the root slash.
ProxyPass /_downloads http://data-files-example.com
ProxyPassReverse /_downloads http://data-files-example.com
When proxying to a https backend you'll also need mod_ssl installed and the directive SSLProxyEngine On.
SSLProxyEngine On
ProxyPass /_downloads https://data-files-example.com
ProxyPassReverse /_downloads https://data-files-example.com
Following code at least rewrites your given original- to your desired target-URL:
<VirtualHost>
SSLProxyEngine On
RewriteEngine On
RewriteCond %{HTTP_HOST} ^our-website-example.com$
RewriteRule "^/_downloads(.*)$" "https://data-files-example.com/$1" [P,L]
</VirtualHost>
This requires the modules mod_ssl, mod_proxy and mod_rewrite to be activated.
Let us know if it was your sought solution and if not, where it went wrong :)

Apache: Rewrite URL in the Background

This question is probably too simple but I cannot get it to work despite hours of testing (and even crashing the server twice o.o ).
The issue is asked frequently: A Tomcat server is accessible through:
"domain.net:8080/theserver/"
and I want it to be accessible directly on "domain.net/".
Just that should also be visible in the user's browser.
The engine "Plesk" which I'm using to configure the site offers a command field for such things. Using the following lines, I've established visible redirecting:
ProxyRequests off
RequestHeader unset Accept-Encoding
RewriteEngine on
RewriteRule ^(/.*) http://www.domain.net:8080/theserver [P]
The redirection doesn't happen in the background though. When I type domain.net into the browser, it switches to "domain.net:8080/theserver/".
What's the right way to make this happen in the background?
"theserver" is the root-location which should be accessible on the server for now.
Huge thanks in advance!
Make sure Rewrite Module of webserver is enabled.
Make sure apache listens on port 80 and 8080 both.
Add this to .htaccess file in the root BUT NOT in the subdirectory "theserver".
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?domain.net$
RewriteCond %{REQUEST_URI} !^/theserver/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://domain.net:8080/theserver/$1
RewriteCond %{HTTP_HOST} ^(www.)?domain.net$
RewriteRule ^(/)?$ http://domain.net:8080/theserver/index.php [L]
You first need to make sure both mod_proxy and mod_proxy_http are enabled in plesk.
Also you should probably either use www or not www.
ProxyRequests Off
RewriteEngine on
RewriteRule ^(.*)$ http://domain.net:8080/myserver/$1 [P]
You can also use the ProxyPass in the server config/vhost.
<Location />
ProxyPass http://domain.net:8080/
ProxyPassReverse http://domain.net:8080/
</Location>
You're just missing ProxyPassReverse. The backend is sending a redirect on the initial URL to add a trailing slash. ProxyPassReverse fixes those redirects for you to use the frontend host/port.
If you control the apache web server, then do you not have to redirect any URL.
Rewriting is supposed to happen for unique requests. If possible, then should the type of rewrite you want get done in the configuration of apache.
First do you have to tell the apache server to listen on port 8080:
listen 8080
Then can you make a virtual host like this:
<VirtualHost *.:8080>
Servername www.domain.net
</VirtualHost>
See for instance:
https://httpd.apache.org/docs/trunk/vhosts/examples.html
and
https://httpd.apache.org/docs/trunk/vhosts/examples.html#port
specifically.
This is much more efficient than using .htaccess, because the latter is parsed at every request, where the solution with virtual hosts is loaded into memory during startup of the server.
Your solution is the other way around. It will make the port visible, because that is the rewrite you create. You want it the other way around and that can be established best by making use of virtual hosts.
A little example of a virtual host:
<VirtualHost www.example.nl:8080>
ServerName www.example.nl
ServerAlias example.nl
DocumentRoot /var/www/theserver
<Directory /var/www/theserver>
etc..
</Directory>
etc...
</VirtualHost>
You may want to actually setup ProxyPass and ProxyPassReverse to accomplish what you are trying to do
ProxyRequests on
ProxyPass / http://IP_OR_LOCALHOST:8080/theserver/
ProxyPassReverse / http://IP_OR_LOCALHOST:8080/theserver/
OR
ProxyPass /theserver/ http://IP_OR_LOCALHOST:8080/theserver/
ProxyPassReverse /theserver/ http://IP_OR_LOCALHOST:8080/theserver/
OR
ProxyPass /anyname/ http://IP_OR_LOCALHOST:8080/theserver/
ProxyPassReverse /anyname/ http://IP_OR_LOCALHOST:8080/theserver/

Can ProxyPass and ProxyPassReverse work in htaccess?

I've never set up a proxy before. I'm using shared hosting, so to set Apache directives, I need to use .htaccess. Can I use .htaccess to do something like below? Any limitations?
ProxyRequests Off
ProxyPass /img/ http://internal.example.com/img/
ProxyPass /app/ http://internal.example.com/app/
ProxyPassReverse / http://internal.example.com/
You cannot use a ProxyPass in an htaccess file. The documentation says it is only applicable in the context:
Context: server config, virtual host, directory
which excludes htaccess (you can't have a <Directory> block in htaccess). However, you can use a ProxyPassReverse to internally rewrite the Location field of proxied requests that cause a redirect. You'll just need to use mod_rewrite's P flag to proxy instead of ProxyPass. So something like:
RewriteEngine On
RewriteRule ^/?img/(.*)$ http://internal.example.com/img/$1 [L,P]
RewriteRule ^/?app/(.*)$ http://internal.example.com/app/$1 [L,P]
ProxyPassReverse / http://internal.example.com/
Just to be clear, you cannot use ProxyPass or ProxyPassReverse in the htaccess file, but you can use ProxyPassReverse with mod_rewrite rules that utilize the P flag.
You can't use ProxyPassReverse, but you can mimic it if you have the ability to rewrite the HTML as it comes back from the origin server.
See my writeup here.