What is the simplest apache mod_proxy configuration for Glassfish? - glassfish

I have a server with Apache2 (on port 80) and Glassfish (on port 8080). I'd like to configure Apache to transparently proxy al request to a certain virtual host to the glassfish Server.
I tried this, but it doesen't work:
<VirtualHost *>
ServerName tognettiimmobiliare.com
ServerAlias www.tognettiimmobiliare.com
ProxyRequests on
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPreserveHost On
ProxyPass / http://tognettiimmobiliare.com:8080/tognettiWEB/
ProxyPassReverse / http://tognettiimmobiliare.com:8080/tognettiWEB/
</VirtualHost>
Can anybody tell me why? Thanks

I am proxying Jenkins and Redmine from a different port with mod_proxy, my configuration looks something like this, sans an additional <Proxy> part which I believe is not needed:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
ProxyPass /jenkins/ http://localhost:8080/jenkins/
ProxyPassReverse /jenkins/ http://localhost:8080/jenkins/
ProxyPass /redmine/ http://localhost:81/redmine/
ProxyPassReverse /redmine/ http://localhost:81/redmine/
There are two things to keep in mind:
The context needs to be the same in both proxy and proxied URLs, like /jenkins/ and .../jenkins/
You should not use external URLs for the proxied page because it will then try to route out to the internet and connect from there, this is slow and firewalls might block the port. Use local machine names or IPs.

I use a simple VirtualHost like so which works.
<VirtualHost *:80>
# ServerName www.itmanx.com
ProxyPass / http://www.itmanx.int/
ProxyPassReverse / http://www.itmanx.int/
</VirtualHost>
make sure you have mod_proxy and mod_proxy_http loaded

I enabled JK on Glassfish by going to Configurations -> server-config -> HTTP Service -> Http Listeners -> jk-listener and enabled it.
Then set up the in my Apache config to proxy this way so the SSL data also gets transmitted.
<Location /util>
SSLOptions +StdEnvVars +ExportCertData
ProxyPass ajp://localhost:8004/util
</Location>
One caveat though, mod_proxy_wstunnel does not seem to work with this or at least I haven't found out how to yet since I use WSS and https://issues.apache.org/bugzilla/show_bug.cgi?id=55320 needs 2.4.10 which is not released yet.

Related

Apache load-balancer: direct to specific application based on URL

I have multiple applications deployed in Tomcat's webapps folder (app1.0, app1.1, app1.2 etc.). When I hit www.example.com:8080/app1.0, the corresponding application appears.
But how to do it on the load-balancing server? For instance, I have a website on which I can click a button (app1.0, app1.1, app1.2 etc.) and an URL pops up like: www.lb.com/app1.0/.../... How to direct to the app based on application version in URL? Use RewriteCond and regex and pass it to ProxyPass? I don't really how to script it, anyone could help? :)
Edit: This is what I done for the 2 apps for 1 Tomcat and 2 apps for 2 Tomcat, but I got 404 sometimes because the Tomcat that has another version has been chosen by the load-balancer.
<VirtualHost *:80>
#Add a http header to explicitly identify the node and be sticky
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
#Declare the http server pool
<Proxy "balancer://plf">
BalancerMember "http://worker1.com:8080" route=worker1
BalancerMember "http://worker2.com:8080" route=worker2
ProxySet stickysession=ROUTEID
ProxySet lbmethod=bybusyness
</Proxy>
#Common options
ProxyRequests Off
ProxyPreserveHost On
#Declare the redirection for the http requests
ProxyPassMatch "/app(.*)" "balancer://plf/app$1"
ProxyPassReverse "/app(.*)" "balancer://plf/app$1"
This is how I did it:
1) define a balancer proxy:
<Proxy balancer://portalcluster stickysession=JSESSIONID>
BalancerMember ajp://TOMCATSERVER1:8009 route=TOMCARSERVER1-0
BalancerMember ajp://TOMCATSERVER2:8009 route=TOMCATSERVER2-100
</Proxy>
2) proxy to it in your VirtualHost:
Listen 443
<Virtualhost *:443>
ServerName example.com
Alias /static /var/www/portalstatic
ProxyPass /static !
ProxyPass / balancer://portalcluster/
ProxyPassReverse / balancer://portalcluster/
</Virtualhost>
NB I removed a lot of configuration from these, that are not related to the question (logs, deny clauses, certificate directives, ...). This is just to illustrate the way I did the proxy.
NB2 I did leave the /static trick since this is usually something you will want to do. Static files must stay on the HTTP, and not send them from Tomcat all the time.

Tableau Reverse Proxy Issue

I want to make Tableau (which is on an internal network) accessible on the public network. One of the ways recommended by Tableau Support is a Reverse Proxy.
I have set up the required modules and have the reverse proxy functioning. The login page is available through these settings in httpd given below. However, once I log in and want to open Projects, Views etc. It routes to
http://actualsite.com/#/vieworproject
which should actually be http://actualsite.com/tableauaccess/#/vieworproject.
Here is the httpd configuration:
ProxyPass /tableauaccess/ http://tableauserverexample.com/
ProxyPassReverse /tableauaccess/ http://tableauserverexample.com/
<Location /tableauaccess/>
Order deny,allow
Allow from all
ProxyHTMLURLMap / /tableauaccess/
</Location>
This doesnt solve the main issue with #. I tried
ProxyPass /#/ http://tableauserverexample.com/#/
ProxyPassReverse /#/ http://tableauserverexample.com/#
But it doesnt help. Any suggestions?? Thanks!
We had this same issue recently. Your httpd.conf file is technically correct for mod_proxy, however the url you are attempting to use is not supported by Tableau. You cannot use:
http://actualsite.com/tableauaccess
But rather you must use the format:
http://tableauaccess.actualsite.com
We ended up setting up that sub-domain name and then using a VirtualHost block such as:
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>
ServerName actualsite.com
DocumentRoot "/path/path2/pathx"
</VirtualHost>
<VirtualHost *:80>
ServerName tableauaccess.actualsite.com
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://tableauaccess.actualsite.com/
ProxyPassReverse / http://tableauaccess.actualsite.com/
<IfModule mod_cache.c>
CacheDisable *
</IfModule>
RequestHeader set X-Forwarded-Proto "http" #or "https", depending on preference
</VirtualHost>
Be sure to double-check your Tableau server to update the URL format.
Sources:
https://community.tableau.com/thread/198095
https://community.tableau.com/thread/218678
(I don't have enough reputation points to post all of my sources, but thanks to Tableau community, shanemadden at ServerFault, and the Apache documentation.)
edit: forgot trailing slashes

How to prevent reverse proxying on certain ports (mod_proxy)?

I am using apache to proxy to tomcat webapps, which works fine. I previously had tomcat listen directly on :8080, so I would like to inform users of my webapp of the move. To that end, I defined a vhost to listen to 8080 where a static html page should be served with the new link. To that end, I defined the following vhost:
Listen 8080
NameVirtualHost domain.example.com:8080
<VirtualHost domain.example.com:8080>
ProxyPass /webapp !
DocumentRoot /var/www/htdocs/vhost-8080
</VirtualHost>
Where the directory vhost-8080 has an index.html with the new link in it.
But every time I load domain.example.com:8080/webapp, I am directed towards tomcat and the webapp, even though domain.example.com:8080/ loads the index.html file I put in the vhost-8080 directory. How can I prevent proxying on this port and only enable it on 80?
For the sake of completeness, here's my proxy configuration:
ProxyPreserveHost On
ProxyRequests Off
<Proxy ajp://localhost/webapp >
Order Deny,Allow
Deny from none
Allow from all
</Proxy>
<Location /webapp>
ProxyPass ajp://localhost:18009/webapp timeout=1200
ProxyPassReverse http://localhost/webapp
</Location>
Tomcat has ajp connector enabled and http connector disabled.

Using go-websocket behind Apache mod_proxy_wstunnel

Note: Updated config and added trailing slash to websocket path. Still same problem
Is it possible to use go-websocket behind a Apache reverse proxy with mod_proxy_wstunnel?
I tried and failed to get things working.
I tried to use the Chat example behind an Apache reverse proxy (with mod_proxy_wstunnel enabled). And it doesn't work. The proxy is a success, while the websocket part does not work at all.
My Apache config looks similar to this:
<VirtualHost *:80>
DocumentRoot /var/www/foobar
ServerName foobar.com
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
ProxyPass /ws/ ws://localhost:8080/ws/
ProxyPassReverse /ws/ ws://localhost:8080/ws/
ErrorLog logs/error_log-foobar
CustomLog logs/access_log-foobar common
LogLevel debug
</VirtualHost>
And of course I'm running the chat server on port 8080. I've tested it with SSH tunnel, and things work perfectly. Then I moved on to Apache.
The first time I tried, the javascript console complains this:
NetworkError: 403 Forbidden - http://foobar.com/ws/
The request seems to be stucked at the origin check.
Then I tried again after comment out the origin check, it get this:
NetworkError: 400 Bad Request - http://foobar.com/ws/
It seems the chat server do not get the upgrade request at all.
How should I debug this?
Where should I start looking?
Thanks everyone! After taking several advices above, I found the solution.
And for someone who might have similar issue, here is the solution to my question:
As Aralo suggested, trailing slash must be added to the WebSocket path (in my case: "/ws/"). It looks Apache will only handle WebSocket with a valid GET request.
James Henstridge was right. The order of ProxyPass relevant. ProxyPass of /ws/ must be put before the / line.
After consulting the Chat example code, I found an origin check in the function ServeWs() and removed.
Everything works now.
And thanks covener, reading logs does help.
I am using Go secure WebSocket (wss://) server behind Apache 2.4.18 on CentOS 7. Here are the settings:
Make sure the system has mod_proxy_wstunnel:
# find /usr/lib64/httpd/modules/ | grep ws
/usr/lib64/httpd/modules/mod_proxy_wstunnel.so
Add the following line in 00-proxy.conf:
# vim /etc/httpd/conf.modules.d/00-proxy.conf
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
Restart Apache:
# systemctl restart httpd
Check the setting:
# httpd -M | grep -iE 'proxy'
proxy_module (shared)
proxy_fcgi_module (shared)
proxy_http_module (shared)
proxy_wstunnel_module (shared)
Edit httpd-vhosts.conf:
# vim /etc/httpd/conf.d/httpd-vhosts.conf
<VirtualHost *:443>
ServerName go.mydomain.com:443
ProxyPreserveHost On
ProxyRequests off
SSLProxyEngine On
SSLCertificateFile "/etc/pki/tls/certs/mydomain.com/mydomain.crt"
SSLCertificateKeyFile "/etc/pki/tls/certs/mydomain.com/mydomain.key"
### The configured ProxyPass and ProxyPassMatch rules are checked
### in the order of configuration. The first rule that matches wins.
ProxyPassMatch ^/(ws(/.*)?)$ wss://192.168.0.1:443/$1
ProxyPass / https://192.168.0.1:443/
ProxyPassReverse / https://192.168.0.1:443/
ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
CustomLog "/var/log/httpd/go.mydomain.com-access_log" common
</VirtualHost>
<VirtualHost *:80>
ServerName go.mydomain.com:80
ProxyPreserveHost On
ProxyRequests off
###
ProxyPassMatch ^/(ws(/.*)?)$ ws://192.168.0.1:80/$1
ProxyPass / http://192.168.0.1:80/
ProxyPassReverse / http://192.168.0.1:80/
ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
CustomLog "/var/log/httpd/go.mydomain.com-access_log" common
</VirtualHost>

Apache + Tomcat: Using mod_proxy instead of AJP

Is there any way I connect Apache to Tomcat using an HTTP proxy such that Tomcat gets the correct incoming host name rather than localhost? I'm using this directive in apache:
ProxyPass /path http://localhost:8080/path
But it comes through as localhost, which is useless when we have a bunch of sites on the same server. I could set the host manually in the server config:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
proxyName="pretend.host" proxyPort="80" />
But that again doesn't serve more than one site. And I don't like the idea of using a different internal port for each site, that sounds really ugly.
Is there no way to transfer the port when I proxy it?
(If you ask why I don't just use AJP, the answer is this error. I'm trying everything I can before giving up on Tomcat and Apache entirely)
The settings you are looking for are:
<VirtualHost *:80>
ServerName public.server.name
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
Note that we're using localhost as the proxy target. We can do this since we enable ProxyPreserveHost. The documentation states that
It is mostly useful in special configurations like proxied mass name-based virtual hosting, where the original Host header needs to be evaluated by the backend server.
which sounds exactly like what you are doing.
I think your best bet if you want multiple sites on the same server is to use virtual hosts in your Apache configuration. Here's an example:
<VirtualHost *:80>
ServerName server.domain.com
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://server.domain.com:8080/
ProxyPassReverse / http://server.domain.com:8080/
<Location />
Order allow,deny
Allow from all
</Location>
As long as you have server.domain.com registered in your external DNS, the incoming host name will be displayed in client URLs. I'm running a single server hosting 6 separate sites, including 3 that are back by Tomcat, using this method.
You can still use AJP, and you should since it's faster than HTTP. Just make sure to enable it in http.conf:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
In that case, this configuration works for me:
<VirtualHost *:80>
ServerName public.server.name
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / ajp://localhost:8080/
# ProxyPassReverse might not be needed,
# it's only for redirecting from inside.
# ProxyPassReverse / ajp://localhost:8080/
</VirtualHost>