Apache Web Server (httpd) - Files over proxy pass - apache

I have an Apache httpd setup with VirtualHost
I am doing some ProxyPass and ProxyPassReverse so I can redirect calls to a local server.
What I want is to have the ability to mock some endpoints with files on the apache server if they exist.
So for example I have the endpoint
http://localhost:8080/myapp/myendpoint
and now when I run
http://localhost/myapp/myendpoint
apache with my VirtualHost setup redirects the calls to my local server
Now lets say I put a file in {apache main dir}/htdocs/myapp/ called myendpoint .
If I remove the Location tag with ProxyPass in VirtualHost calling
http://localhost/myapp/myendpoint returns the results of the file in htdocs. But if I leave the above Location tag in the configuration it ignores the file and goes to the server.
How can I configure Apache Web Server to give priority to the file before doing the proxypass?

Instead of
ProxyPass /localhost/myapp/ http://localhost:8080/localhost/myapp/
ProxyPassReverse /localhost/myapp/ http://localhost:8080/localhost/myapp/
You can try with
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /localhost/myapp/ http://localhost:8080%{REQUEST_URI} [P]
ProxyPassReverse /localhost/myapp/ http://localhost:8080/localhost/myapp/
(http://httpd.apache.org/docs/current/rewrite/flags.html#flag_p, notice the Performance warning)

Related

Configure Apache for Angular and Tomcat on the same host

I am trying to serve my application on a Centos 7 host, where I have deployed an Angular app for the frontend and Java Spring Boot app for the backend.
My versions are Apache 2.4.6, Tomcat 9 and Angular 7.
Let's say my domain is example.com. I want the user to write the following on the browser to access the Angular app routes, i.e. the frontend:
example.com/**
Also I would like to be able to write the following on the browser to access the Java app routes, i.e. the backend:
example.com/api/**
I tried to do it using Apache's mod_proxy, after reading this post: https://stackoverflow.com/a/33095758/350061. However, I only managed to serve Angular through example.com, while my API is only served on its original endpoint, that is example.com:8080/my-api and not through example.com/api.
These are my Apache settings:
/etc/httpd/conf.d/example.conf
<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
DocumentRoot "/var/www/my-ng-app/dist/my-ng-app"
RewriteRule ^/api/(.*) http://localhost:8080/$1 [P,L,QSA]
ProxyPassReverse /api/ http://localhost:8080/
</VirtualHost>
/var/www/my-ng-app/.htaccess
RewriteEngine On
RewriteRule ^api/(.*) http://localhost:8080/my-api/$1 [P,L,QSA]
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
I have configured .htaccess to be read from that folder and verified that it is actually read. Also even if I remove the last part of .htaccess that redirects non-existing resources to index.html, the api does not get served from example.com/api, as I wish. It only gets served from example.com:8080/my-api
Any ideas on how to configure it?
After a long time of googling and trial and error, my solution consists of these changes:
I edited Tomcat's server.xml connector to serve requests through localhost. This made possible for rewrite settings to access my Java app through localhost:8080, but made impossible for me to access remotely my Java app through example.com:8080, which is fine.
I configured SELinux to allow Apache (httpd) to initiate outbound connections, in my case connections to localhost
I applied some fixes on my original VirtualHost and .htaccess configuration
More specifically:
sudo nano /opt/tomcat/latest/conf/server.xml
Find the connector for port 8080 and add address attribute as such:
<Connector port="8080" protocol="HTTP/1.1"
address="127.0.0.1"
connectionTimeout="20000"
redirectPort="8443" />
/usr/sbin/setsebool -P httpd_can_network_connect 1
The -P persist the setting for future reboots
/etc/httpd/conf.d/example.conf
<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
DocumentRoot "/var/www/my-ng-app/dist/my-ng-app"
RewriteRule ^/api/(.*) http://localhost:8080/my-api/$1 [P,L,QSA]
ProxyPassReverse /api/ http://localhost:8080/my-api/
</VirtualHost>
/var/www/my-ng-app/.htaccess
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
After these changes just restart Tomcat and Apache and you will be able to access your API through example.com/api

How to configure Apache virtual hosts based on referer?

We have a tomcat web server running in port 8080 and Apache server running in port 80 in windows environment. Our objective is to configure, Apache server as proxy server to hide the tomcat web server address to the users.When i tried to use mod_rewrite based on HTTPREFERER rule it's working fine but user can able to see the redirected URL in the browsers network tab.
RewriteEngine on
RewriteMap deflector "txt:C:/gsasetup/gsaproxy01/Apache24/conf/deflector.map"
RewriteCond "%{HTTP_REFERER}" !=""
RewriteCond "${deflector:%{HTTP_REFERER}}" "=-"
RewriteRule "^" "%{HTTP_REFERER}" [R,L]
RequestHeader set Authorization "Basic dXNlcjpwYXNzd29yZA==" env=DOAUTH
RewriteCond "%{HTTP_REFERER}" !=""
RewriteCond "${deflector:%{HTTP_REFERER}|NOT-FOUND}" "!=NOT-FOUND"
RewriteRule "^" "${deflector:%{HTTP_REFERER}}" [R,L]
Similarly, when i tried using virtual hosts configuration it's internally redirecting the requests to tomcat web server running in port 8080.
ServerName localhost
ServerAlias *.localhost
ProxyRequests off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
But here what i want is the combination of both. Means proxy should happen only for specific referrer. Otherwise i want to send user unauthorized response.
Is this kind of configuration possible?

apache2 rewrite rule without changing URL

This below rewrite redirects localhost to http://www.example.com/?id=211&test=1 but I want that localhost on browser should not be changed but the page will come form the above link.
I am using this rewrite rule on my Apache conf:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^localhost$ [OR]
RewriteRule ^/?$ http://www.example.com/?id=211&test=1 [L]
This below rewrite redirects localhost to
http://www.example.com/?id=211&test=1 but I want that localhost on
browser should not be changed but the page will come form the above
link.
If you want to load a page from elsewhere without chaining the URL, mod_rewrite is the wrong tool for the job. Use mod_proxy instead. First enable it in Apache like this; example assumes you are on Ubuntu 12.04 but should work on most any Linux Apache install
sudo a2enmod proxy proxy_http
Then set this to enable a reverse proxy from your root path of / to http://www.example.com/?id=211&test=1:
<IfModule mod_proxy.c>
# Proxy specific settings
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://www.example.com/?id=211&test=1
ProxyPassReverse / http://www.example.com/?id=211&test=1
</IfModule>
EDIT: Seems like mod_proxy and query strings for the destination do not mix; emphasis mine:
This directive allows remote servers to be mapped into the space of
the local server; the local server does not act as a proxy in the
conventional sense, but appears to be a mirror of the remote server.
The local server is often called a reverse proxy or gateway. The path
is the name of a local virtual path; url is a partial URL for the
remote server and cannot include a query string.
So if there is anyway you could set another page—maybe on localhost—that would bounce it behind the scenes. Meaning this happens on localhost:
ProxyPass / bounce.php
And then the file, bounce.php could have this line in it:
<?php
header('Location: http://www.example.com/?id=211&test=1');
?>
Which would allow mod_proxy to have a valid destination. And then the PHP file does the redirect? Hard to say, but the query string on your destination server is the issue.

Apache rewrite or proxy with redirect of internal server

I am trying to use Apache as a proxy for an internal tomcat server, but the tomcat server performs a redirect that got me crazy
I first tried mod_proxy through:
ProxyPass / ajp://127.0.0.1:8045/bv-via-web/
ProxyPassReverse / ajp://127.0.0.1:8045/bv-via-web/
When accessing / (root) the internal server performs a redirect to /bv-via-web/hola which doesn't exist. It should redirect to /hola. How can I achieve this through the Apache config?
As a workaround I though I add the following:
ProxyPass /bv-via-web/ ajp://127.0.0.1:8045/bv-via-web/
ProxyPassReverse /bv-via-web/ ajp://127.0.0.1:8045/bv-via-web/
But that doesn't work as it will extend the url to an internal request of bv-via-web/bv-via-web/hola. So basically I want to change the url but don't know how that is possible with mod_proxy.
I then tried mod_rewrite, with the following:
RewriteEngine on
RewriteRule ^/bv-via-web/(.*)$ http://127.0.0.1:8040/bv-via-web/$1 [P,L]
RewriteRule ^/(.*)$ http://127.0.0.1:8040/bv-via-web/$1 [P,L]
But then when I open the root of the website it performs a redirect and http://127.0.0.1:8040/bv-via-web/hola appears in the browser address.
I don't understand, as it should work as an internal proxy due to the [P] flag.
What am I doing wrong ?
I solved it by adding:
ProxyPreserveHost On
Such it's not forwarded to the 127.0.0.1 as mentioned above.
So the total config snippet is:
RewriteEngine on
RewriteRule ^/bv-via-web/(.*)$ http://127.0.0.1:8040/bv-via-web/$1 [P]
RewriteRule ^/(.*)$ http://127.0.0.1:8040/bv-via-web/$1 [P]

Apache Rewrite Rules for CentOS Grails Application with Tomcat

I am using Apache and Tomcat on a CentOS box and I want to do the following rewrites:
I want to handle abc.com to redirect to www.abc.com when a request is made.
I want to load my resources with Apache instead of Tomcat
This is my conf file. It is located in /etc/httpd/conf.d/tomcat.conf
#
# This configuration file enables the default "Welcome"
# page if there is no default index page present for
# the root URL. To disable the Welcome page, comment
# out all the lines below.
#
RewriteEngine on
RewriteRule ^/images/(.*) /images/$1
RewriteRule ^/css/(.*) /css/$1
RewriteRule ^/js/(.*) /js/$1
RewriteCond %{HTTP_HOST} ^abc\.com
RewriteRule ^(.*)$ http://www.abc.com$1 [R=301,L]
NameVirtualHost *:80
<VirtualHost *:80>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / ajp://127.0.0.1:8009/
ProxyPassReverse / ajp://127.0.0.1:8009/
ProxyPassReverseCookiePath / /
</VirtualHost>
My AJP proxy rewrite is working, I just need to do the following rewrites above.
apache redirect from non www to www
To load your resources with apache instead of tomcat, you can:
use apache mod_cache module, so you can decrease your tomcat load dramatically by caching your resources (css, js, images)
add servlet filters in your web application to set http cache headers in order to enable caching