How to configure Apache virtual hosts based on referer? - apache

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?

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

mod_rewrite - Port 80 does not change to 443 when HTTP is explicitly requested

I have an app deployed to Elastic Beanstalk whose Tomcat container uses Google OpenID Connect for authentication. I want to redirect all http requests to https, for which I have the following mod_rewrite configuration in a file in .ebextensions -
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
Google OAuth2 credentials console has https://example.com/j_security_check as an authorized redirect URL. The configuration works fine when either example.com or https://example.com is requested, whereupon the app is redirected to the mentioned authorized URL.
However, when http is explicitly requested - http://example.com - the app is being redirected to https but port 80 is still being used. The authorized redirect URL then becomes https://example.com:80/j_security_check and I get Error: redirect_uri_mismatch.
How can I redirect explicit http requests to https with the port changed to 443? The main goal is to match the mentioned authorized redirect URL. If possible, I'd like to implement this with the .ebextensions configuration file or a similar solution.
Can you something like this. If it got worked I will give you the explanation.
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
The problem was not with the rewrite rule. The file had to be placed in a specific path within .ebextensions for it to work in Tomcat 8. The configuration files had to be setup differently too. Most examples provided were not for Tomcat so I ended up putting them in the wrong location.
What worked -
In /.ebextensions/httpd/conf.d/myconf.conf, place -
LoadModule rewrite_module modules/mod_rewrite.so
and in /.ebextensions/httpd/conf.d/elasticbeanstalk/00_application.conf, place -
<VirtualHost *:80>
<Proxy *:80>
Order Allow,Deny
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
Take note of the use of .conf files instead of .config. This is important!
Also, the redirection that I was getting was not genuine. I was not paying close attention, because when I requested example.com, the browser cache was serving me https://example.com. It was not actually redirecting an http request to https.

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 SSL Proxypass gives unsecured content for zope

Had hit a roadblock with the apache configuration trying to redirect or proxy to other webservers. Have google for quite a while but am stuck as mentioned in the scenario below. Apart from using apache for some out of the box web applications like Plone, cmdbuild, etc., I don’t have much experience with apache. Leaving security aside for the configuration for Apache, am I trying to achieve something the wrong way. Do give me your views and other possible ways to achieve what I am trying to do. Am planning to run all the sites under https.
Scenario:
Server 1 – 10.0.0.1 (CentOS 6.5)
Apache (version 2.2.5) running on port 80 (SSL enabled) – Main Web Server
Zope (Plone) running on port 8080
Sites:
http://10.0.0.1:8080/site1
http://10.0.0.1:8080/site2
Server 2 – 10.0.0.2 (CentOS 6.5)
Tomcat running on port 8080
Sites: http://10.0.0.3:8080/site3
Server 3 – 10.0.0.3 (Windows Server 2008)
IIS running on port 80
Sites: http://10.0.0.4/site4
If ProxyPass and Proxy PassReverse is used on the apache ssl.conf like below:
ProxyPass /site1 http://10.0.0.1:8080/site1
ProxyPassReverse /site1 http://10.0.0.1:8080/site1
ProxyPass /site2 http://10.0.0.1:8080/site2
ProxyPassReverse /site2 http://10.0.0.1:8080/site2
ProxyPass /site3 http://10.0.0.2:8080/site3
ProxyPassReverse /site3 http://10.0.0.2:8080/site3
ProxyPass /site4 http://10.0.0.1:8080/site4
ProxyPassReverse /site4 http://10.0.0.1:8080/site4
Site 3 and Site 4 are working properly fine with the ssl enabled but site 1 and site 2 (running under localhost zope) are working too but the contents are not showing properly because
“Connection Partially Encrypted
Parts of the page you are viewing were not encrypted …..”
If RewriteEngine is used instead of ProxyPass as shown below, both site1 and site2 runs perfectly under ssl.
RewriteEngine On
RewriteRule ^/(.*) http://10.0.0.1:8080/VirtualHostBase/https/%{SERVER_NAME}:443/site1/VirtualHostRoot/$1 [L,P]
But the other sites site3 and site4 are not reachable.
Apache httpd.conf just had a permanent redirect to https
<VirtualHost *:80>
Redirect permanent / https://10.0.0.1/
</VirtualHost>
If your rewrite rule is working for anything other than site1, it's because acquisition is making other sites appear inside site1. You don't want to depend on that.
Instead, have a separate rewrite rule for each site:
RewriteEngine On
RewriteRule ^/site1(.*) http://10.0.0.1:8080/VirtualHostBase/https/{SERVER_NAME}:443/site1/VirtualHostRoot/$1 [L,P]
RewriteRule ^/site2(.*) http://10.0.0.1:8080/VirtualHostBase/https/{SERVER_NAME}:443/site2/VirtualHostRoot/$1 [L,P]
RewriteRule ^/site3(.*) http://10.0.0.2:8080/VirtualHostBase/https/{SERVER_NAME}:443/site3/VirtualHostRoot/$1 [L,P]
RewriteRule ^/site4(.*) http://10.0.0.1:8080/VirtualHostBase/https/{SERVER_NAME}:443/site4/VirtualHostRoot/$1 [L,P]
Don't try to do this with one rewrite rule, or you'll expose your Zope root via proxy. A bad idea.

Rewrite from https to http

I have 5 sites on one apache server. One of the sites is with SSL. So when the other sites are accessed with https then they are redirected to the SSL site which is incorrect.
E.g.
https://x.com (with SSL)
http://y.com (normal site no SSL)
If I access https://y.com then I get the content from x.com. How can I fix so https://y.com just gets rewritten to http://y.com?
In your .htaccess put:
RewriteCond %{HTTPS} on [NC]
RewriteRule ^(.*)$ http://y.com/$1 [R=301,L]
You can define it in apache config file. You must add a rule to connection incoming from https port.
If you are using linux, propably you have this config in /etc/apache2/sites-available/default-ssl.
If you don't have this file you must searching https virtualhost:
<IfModule mod_ssl.c>
<VirtualHost _default_:443>