How to Use Apache to Proxy to Single Page Application on Weblogic Cluster - apache

As part of upgrading a legacy Java application (hosted on Weblogic cluster), one section of this application will be replaced by a single page application (REACT), calling out over an API to various services that contain migrated backend functionality. For now until all UI dependencies are ported off the legacy application, the REACT SPA will still be hosted inside a JSP page (some common JSP code has not been ported, and so will be present on the JSP page hosting the react app).
The infrastructure hosting this setup is currently an Apache server, routing to the Weblogic cluster or newer services as needed. Proxying to the weblogic cluster was simple before, as all *.jsp pages were routed to the cluster with a simple weblogic plugin block:
<IfModule mod_weblogic.c>
WebLogicCluster server1:port,server2:port
MatchExpression *.jsp
</IfModule>
However with the new SPA, I also need a whole set of routes to proxy to a single .jsp page containing my SPA. If my goal was only to proxy by path, I could solve that easily with apache weblogic plugin:
<Location /newSection/>
WLSRequest On
WebLogicCluster server1:port,server2:port
PathTrim /newSection/
PathPrepend SPA.jsp
DefaultFileName SPA.jsp
</Location>
However this only works for the base /newSection/ url, as a url like
http://host/newSection/spa-route
gets proxied to
http://host/SPA.jsp/spa-route
which is obviously not valid.
No amount of PathTrim, PathPrepend, or anything else I try for the weblogic plugin solves the problem that I am trying to proxy by path to a single URI (everything needs to proxy to http://host/SPA.jsp, SPA router handles the rest)
I am currently experimenting with just using mod_rewrite and mod_proxy instead, as RewriteRule [P] allows me to proxy to a single URI on the cluster (cluster IP coming from Proxy balancer). However this is much more complicated to set up (still trying), and I have to implement things like session stickiness myself.
A solution for how to use the mod_weblogic plugin to proxy to a particular URI would be great, but examples of how to use mod_rewrite, mod_proxy, and/or mod_proxy_balancer to achieve this proxying to a single URI on a weblogic cluster would be extremely helpful as well.

Turns out there was an apache feature (Passthrough) I was not aware of (or at least how exactly it works) that can bridge Apache rewrite rules to the weblogic plugin nicely.
RewriteRule /newSection/.*$ /SPA.jsp [PT,L]
The passthrough rewrites the URI to http://host/SPA.jsp WITHOUT doing a rewrite. The passthrough then explicitly passes that new URI back through the rule stack and other modules. At this point the original weblogic plugin rule I had that proxies by MIME type to the cluster (*.jsp) will pick up the URI and work nicely.
This way Apache takes care of rewriting a set of paths to a specific URI, and the weblogic plugin nicely takes care of the rest (proxying to cluster, load balancing, sticky sessions, etc.)

Here is how you use weblogic plugin to direct individual urls, feel free to change options as per your requirement:
Create a virtual host file:
<VirtualHost *:80>
SSLEngine on
ServerName fqdn
ServerAlias alias
ServerAdmin webmaster#localhost
Header always append X-Frame-Options DENY
DocumentRoot /var/apache2/htdocs
<Directory /var/apache2/htdocs>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<IfModule mod_weblogic.c>
debug ERR
FileCaching on
WLIOTimeoutSecs 600
Idempotent ON
FileCaching ON
DynamicServerList ON
KeepAliveEnabled OFF
<Location /newsection>
SetHandler weblogic-handler
WebLogicCluster host1:port,host2:port
</Location>
<Location /newsection/SPA.jsp>
SetHandler weblogic-handler
WebLogicCluster host3:port,host4:port
</Location>
<Location /SPA.jsp>
SetHandler weblogic-handler
WebLogicCluster host5:port,host6:port
</Location>
</IfModule>
</VirtualHost>

Related

Allow internet users to access privately hosted website pages

I have a corporate private network(VPN) and on one VM a website is hosted which can be accessed internally only. e.g. https://internal.com/welcome.html
Now, I want to allow few pages of the site to be accessible from outside but with their own url.
e.g. they will open http://theirdoamin.com/welcome.html which will be redirected into my private network and internally it will be mapped/proxied to https://internal.com/welcome.html.
This way outside will never know the actual url (i.e https://internal.com/welcome.html.
My question is, can we achieve this using Apache Reverse proxy server sitting in-front of my hosted VM?
Second question, can I also limit the access to welcome.html page only and not others?
My colleague already implemented using Apache Nifi but I still believe it can be simple done using Apache Reverse Proxy setup.
Please advise.
Thanks
1) Yes, Apache reverse-proxy is able to do that.
2) You can limit access as you like.
1) I'd set up two vhosts (for examples), one with the original name and one with the VPN-accessable name.
Listen 80
#If you are running a Apache 2.2 you'll need the following line, for 2.4 you won't
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot "srv/www/example1"
ServerName internal.com
<Directory "/srv/www/example1">
Require all granted
</Directory>
# Other directives here, if needed
</VirtualHost>
<VirtualHost *:80>
ServerName external.com
ProxyPreserveHost On
RewriteEngine On
RewriteRule ^ https://internal.com/welcome.html [P]
ProxyPassReverse / https://internal.com/
</VirtualHost>
You'll need the RewriteRule to target a specific file instead of a whole domain. Otherwise a simple ProxyPass would have been enough.
This requires the modules mod_rewrite, mod_proxy and mod_proxy_http to be activated.
2) is done by the RewriteRule. It only allows access to that specific target-file (welcome.html).

Apache 2, mod_fastcgi, REST: Handle requests to different URIs with the same application

I am trying to develop a RESTful service using Apache 2 and mod_fastcgi as my transport and security layer.
What I am trying to achieve is that a C++-application is called when a request is made. Then I want to use the HTTP method and the URI to decide (inside the application) which of the (internal) resources should be accessed and in which way.
Calling my C++-FastCGI application works (located # /var/www/html/foo/fastcgi_test). But only with a specific URI - the URI where my binary is located:
If I open http://127.0.0.1/foo/fastcgi_test in a browser my application runs and returns a html test page like I want.
Trying e.g. http://127.0.0.1/foo/bar returns a page with a 404. But I would like the same application to be called (fastcgi_test).
My configuration (so far) looks like this:
<IfModule mod_fastcgi.c>
FastCgiIpcDir /var/lib/apache2/fastcgi
<Location /foo>
SetHandler fastcgi-script
</Location>
FastCgiServer /var/www/html/foo/fastcgi_test -flush
</IfModule>
I read the mod_fastcgi manual and dug through the Apache manuals, but I can't find the right hint. It seems I don't seach for the right key word.
As I am very new to Apache configuration I maybe/hopefully just miss the right starting point.
How do I configure Apache/mod_fastcgi to send requests to a "branch of URIs" to the same FastCGI process? Can somebody provide a pointer?
The key is to use an alias. I also moved the FastCGI program out of the content area of Apache into a separate directory (/var/www/fastcgi).
My solution looks like this:
<IfModule mod_fastcgi.c>
FastCgiIpcDir /var/lib/apache2/fastcgi
<Directory /var/www/fastcgi>
SetHandler fastcgi-script
</Directory>
<Location "/foo">
Require all granted
</Location>
FastCgiServer /var/www/fastcgi/fastcgi_test -flush
AliasMatch "/foo(.*)" "/var/www/fastcgi/fastcgi_test"
</IfModule>

new session after every request, tomcat backend, apache frontend

I develop a jsp website using tomcat as backend and apache as frontend redirecting with mod_proxy.
First my configs.
apache:
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLProxyEngine on
ProxyPass / https://realdomain.tld:8443/proj1/
ProxyPassReverse / https://realdomain.tld:8443/proj1/
<Location />
Order allow,deny
Allow from all
</Location>
When I reload my jsp webpage, every time i get a new session id. When developing on localhost without apache and mod_proxy everything works and I keep the same session id.
For my webapp it is important to keep the same session during the time.
Any Idea how i can tell apache to keep my session. I guess apache has to redirect the cookie to tomcat right? but how...
Any time you change the context path in the proxy (/ -> proj1) you create a whole heap of problems to solve. Your immediate cookie problem can be solved with the ProxyPassReverseCookiePath directive. I then suspect you'll find the next problem to solve. You'd be better off redeploying your application as the ROOT web application so that your ProxyPass directive is ProxyPass / https://realdomain.tld:8443/
As an aside, it looks like you are proxying to Tomcat's https connector. If you aren't careful you will create security problems for yourself if httpd receives requests over http, proxies them to Tomcat over https and Tomcat treats those requests as being received over a secure channel.

Apache httpd as load balancer for jboss as well another Apache servers

I have an apache httpd server, say server1* (publicly exposed) that is acting as load balancer for some jboss servers(behind firewall) using mod_cluster. Now I want to install my static content (images/css/htmls) and probably some cg-scripts on a couple of apache servers, say **server2 and server3 (behind firewall).
Now I want server1 to act as load balancer for these server2 and server3 as well along with the jboss servers.
With this arrangement, any request for applications deployed on jboss need to be routed to jboss and any static content request should go to server2 or server3.
Here are the versions I am using
Linux Server
apache httpd - 2.2.22
JBOSS-EAP-6
What mechanism/configuration do I need to use in server1 to make it possible?
Please see if someone can help with this.
Well, you just add a ProxyPass setting. mod_cluster is compatible with ProxyPass, so you can use both.
For instance, if I would like gif images to be served by httpd, not by AS7, I can add:
ProxyPassMatch ^(/.*\.gif)$ !
Furthermore, if you set
CreateBalancers 1
mod_cluster won't create proxies for you and you have to do it yourself. This gives you an additional control. For instance:
ProxyPassMatch ^/static/ !
ProxyPass / balancer://qacluster stickysession=JSESSIONID|jsessionid nofailover=on
ProxyPassReverse / balancer://qacluster
ProxyPreserveHost on
In the aforementioned example, we proxy anything but /static/ content to the workers.
Note:If you encounter any cookies related issues, you might want to play with ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath.
Note qacluster in my config. The default is mycluster, so for naming my balancer qacluster, I added this to mod_cluster config (outside VirtualHost):
ManagerBalancerName qacluster
If it is not clear, just reply and I can try to elaborate further.
I had the same issue where in we were using Apache HTTP server for static content and JBOSS AS 7 server for dynamic contents (the JSF web app).
So adding the below property at the end of Load modules tells
CreateBalancers 0
Tells to "0: Create in all VirtualHosts defined in httpd."
More at: http://docs.jboss.org/mod_cluster/1.2.0/html/native.config.html#d0e485
And the below config solved the issues of images and styel sheets not getting displayed.
<VirtualHost *:80>
ServerName dev.rama.com
DocumentRoot "/var/www/assests"
UseAlias 1
ProxyPassMatch ^(.*\.bmp)$ !
ProxyPassMatch ^(.*\.css)$ !
ProxyPassMatch ^(.*\.gif)$ !
ProxyPassMatch ^(.*\.jpg)$ !
ProxyPassMatch ^(.*\.js)$ !
ProxyPassMatch ^(.*\.png)$ !
<Directory /var/www/assests>
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
Note:
All our assests for the web app was on HTTP server at
/var/www/assests and the url I was accessing was dev.rama.com on port 80
So when it sees this ProxyPassMatch ^(.*.css)$ !
The webserver knows that the css files are local to the http server and we dont need to go to Jboss App server.
More info at http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass

How to rewrite / proxy an Apache URI to an application listening on a specific port / server?

They say that Apache's mod_rewrite is the swiss-army knife of URL manipulation, but can it do this?
Lets say I want to add a new application to my Apache webserver, where the only configurable option of the app is a port number.
I want to use & give out URLs of the form "http://hostname.example.com/app" rather than "http://hostname.example.com:8080". This would ensure that clients would be getting through the institution's firewall as well, and it's generally tidier.
My application includes absolute URIs in php, javascript and css, so I want to prepend my own root location to the URI in the applications internal links. I have no access to DNS records and so can't create another name-based virtual server.
Using Apache's mod_rewrite and mod_proxy modules, I can transparently redirect a client to the correct home-page of the application. But links within that homepage don't point a client to links relative to the new base URL.
So, what's the best way of proxying a request to an application that is listening on a specific port?
For example, if I had an application listening on port 8080, I could put this in my Apache configuration:-
<VirtualHost *:80>
SSLProxyEngine On
ServerName myhost.example.com
RewriteEngine On
UseCanonicalName On
ProxyVia On
<Location "/application">
RewriteRule ^/application/?(.*) http://localhost:8080/$1 [P,L]
</Location>
</VirtualHost>
This would work fine if the application didn't use absolute URLs, but it does. What I need to do is rewrite URLs that are returned by the application's css, javascript and php.
I've looked at the ProxyPass and ReverseProxyPass documentation, but I don't think these would work..?
I've also come across Nick Kew's mod_proxy_html, but this isn't included in the standard Apache Distribution, and my institution's webserver seems to have been fine for years without it.. Other than trawling manually (or using a grep -r | sed type expression) through the application's source code, or using this 3rd party add-on, are there any other ways to go about this?
Could I perhaps use some of the internal server variables in a mod_rewrite rule? For example a rewrite rule based on ’HTTP_REFERER'?
Using mod_proxy would work just fine. For instance, I mapped https://localhost/yalla/ to point to a subdirectory of my webserver:
LoadModule proxy_module modules/mod_proxy.so
ProxyRequests On
<Proxy *>
Order deny,allow
Allow from localhost
</Proxy>
ProxyPass /yalla/ http://yalla.ynfonatic.de/tmp/
If you implement this, you'll note that the pictues of the directory-listing aren't visible; this is because they're below the /tmp/ directory on the remote server, hence not visible.
So, in your case you'd do:
LoadModule proxy_module modules/mod_proxy.so
ProxyRequests On
<Proxy *>
Order deny,allow
Allow from localhost # Or whatever your network is if you need an ACL
</Proxy>
ProxyPass /app/ http://hostname.example.com:8080/
Like with everything in Apache configuration, watch those trailing slashes when referring to directories.
Good luck!
Alex.