Premise:
I have a custom webserver running on port 2480. I don't really know how it works, but it has it's own www dir. Inside this dir, there is an index.htm file which is executed by default. Inside that file, there is
<meta http-equiv="refresh" content="0;URL=/studio/index.html">
So, I immediately get redirection to 107.0.0.1:2480/studio/index.html. However, I can't find such "studio" folder anywhere in my filesystem (I have no idea how this works).
Question:
In the same server, I have an Apache webserver running on port 80. I'd like to configure a reverse proxy so that "127.0.0.1:80/foo" is equal to "127.0.0.1:2480".
I did in apache2.conf:
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
ProxyPass /foo http://localhost:2480/
ProxyPassReverse /foo http://localhost:2480/
Then, I navigate to "127.0.0.1:80/foo". I see that it correctly connects to "127.0.0.1:2480/index.htm". But then, index.htm immediately redirects to "/studio/index.html", and I see the url changes to "127.0.0.1:80/studio/index.html. I get then "403 forbidden". But this is a "fake forbidden", because doing this it is just looking for "/studio/index.html" in the default apache document root dir, which of course does not exists (and htaccess is configured to deny all by default).
So question is:
"127.0.0.1:80/foo" resolves correctly to "127.0.0.1:2480/index.htm"
"index.htm" redirects to "/studio/index.html"
why is apache looking for "127.0.0.1:80/studio/index.html" instead of "127.0.0.1:2480/studio/index.html" ?
How should this be done?
Thanks a lot
Related
I have spent quite some time trying to figure out something apparentaly pretty trivial, but my lack of knowledge in Apache/Tomcat isn't making this easy for me.
I was asked to redirect a request coming on port 80 (Apache) to port 8080 (Tomcat.. and when that will work, to an app).
Before I changed anything, localhost:80 would show "It works" and locahost:8080 the Apache welcome page.
I did the following changes :
uncommented LoadModule proxy_module modules/mod_proxy.so & LoadModule proxy_http_module modules/mod_proxy_http.so from the httpd.conf file
uncommented Include conf/extra/httpd-vhosts.conf, always in httpd.conf
In httpd-vhosts.conf, I added :
<VirtualHost *:80>
ServerName localhost
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</VirtualHost>
But when I try http://localhost, I do arrive on Apache welcome page, but all css styling, images, are missing :
I have an idea why it is not working : when I inspect my page, and look at the header i see that the link to the favicon for example is http://mydomain/myApp/images/favicon.ico, but if I copy paste that link, I will of course not find the favicon because it is not on Apache, but Tomcat (if that makes any sense). If I add the port to the URL, then it works : http://mydomain:8080/myApp/images/favicon.ico
Has this anything to do with the problem stated here : https://serverfault.com/questions/561892/how-to-handle-relative-urls-correctly-with-a-reverse-proxy ?
This is because the tomcat response headers will contain the proxy headers (i.e. the Location header is http://localhost/WebApp rather than http://localhost:8080/WebApp) because ProxyPreserveHost is switched On
So I switched it to Off :
<VirtualHost *:80>
ServerName localhost
ProxyRequests Off
ProxyPreserveHost Off
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</VirtualHost>
But the page still will not show correctly.
Thank you for your input.
Just figured this one out myself. Solution is to add a / to the end of the addresses in the ProxyPass lines.
As far as I understand it, the server is trying to resolve the address literally, so when it checks for, say the docs page, which is in the webapps folder, it returns a proxy error that says that it can't resolve http://localhost:8080docs.
This is the first time I have to do something like this. I'm developing a front end application with some stuff I cannot change - it requests some specific address for the serverside data.
I need to redirect all those requests to say:
https://192.168.1.1:8443/server
to a different address, say
https://192.168.100.100:8443/server
I figured this is a job for Reverse Proxy and google brought me to httpd.
Now I work on Windows 7 machine, I've managed to get Apache24 binaries and started it on default 80 port, 127.0.0.1 says "It works!".
I tried to configure a virtual host but no matter what I do, I cannot get it to redirect.
I'm just trying to test the basic stuff first.
I've enabled required mods:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
I've uncommented following include:
Include conf/extra/httpd-vhosts.conf
And inside that file I got this:
<VirtualHost *:80>
ServerName mytest.com
ProxyPass /proxy/ http://myip:tomcatport/myapp/
ProxyPassReverse /proxy/ http://myip:tomcatport/myapp/
</VirtualHost>
I've looked through quite a few of tutorials on how to configure it and tried half a dozen different combinations of the same basic things, configured in this VirtualHost, but no matter what I do, I cannot get it to work.
From what I gathered, this configuration should redirect my browser from mytest.com to http://myip:tomcatport/myapp/, what am I doing wrong here?
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.
I am running into issues with cakephp application running with CentOs. I did not change any setting in the default config other than added a file under conf.d which content as :
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot /var/www/portal/
ServerName abc.mydomain.com
</VirtualHost>
When accessed, home page works i.e. app.mydomain.com shows up but none of the CSS,JS and img files are loaded which are under default structure
i.e. /var/www/portal/app/webroot/img
/var/www/portal/app/webroot/css
/var/www/portal/app/webroot/js
So I tried moving them right under /var/www/portal/ and that worked for homepage but clicking on any link on homepage just does 404. e.g. If link is abc.mydomain.com/test
In apache log I see the errors as 'File Does not exist : /var/www/portal/test' . It seems that apache is not sending the request to cakephp to process the url.
What could be wrong here? Most likely with the apache security settings but am not sure where to lool.
Is your AllowOverride set to all? Only then the CakePHP rewrite directives which are in .htaccess files start working. Alternatively, you can move them to the virtual host configuration and get them to work.
Ok, this is a common mistake. you should enable "rewrite" --> module rewrite. (this is of course a php module). in ubuntu you usually type sudo a2enmod rewrite. Check for CentOS command.
I have a single Tomcat instance containing a number of webapps, each accessible via it's /Context. Tomcat is behind httpd (actually Debian Apache2), configured with virtual hosts to serve each app/Context. Tomcat connectivity is with mod_jk.
This works fine when I don't care about removing the context from urls: when the root of a virtual domain is requested, the requested is redirected to domain.com/Context.
However for one app I do want to remove the context. I believe this can be done by using mod_rewrite, and passing the re-written url to mod_jk for passing on to the correct Tomcat context. So my Debian Apache2 sites-available file looks like this:
NameVirtualHost *
<VirtualHost *>
ServerName domain.be
DocumentRoot /home/webapp/app/static/domain/
RewriteEngine on
RewriteRule ^/(.*)$ /Context/$1 [L,PT]
RewriteLog "/var/log/apache2/domain-rewrite.log"
RewriteLogLevel 4
JkLogFile /var/log/apache2/domain-mod_jk.log
JkLogLevel debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkMount /Context w1
JKMount /Context* w1
JkOptions +ForwardURICompat
ErrorLog /var/log/apache2/domain_error.log
CustomLog /var/log/apache2/domain_access.log combined
LogLevel warn
</VirtualHost>
According to the docs, the [PT] flag and +ForwardURICompat options should result in the rewritten URL being passed to jk_mod. However that doesn't seem to be happening.
The URL is being re-written, but it seems as if mod_jk is ignoring it: A request for domain.be/Context for example gets rewritten as /Context/Context - but is still handed to mod_jk as /Context.
Any ideas? Incidentally, I cannot use mod_proxy at the moment.
Thanks
#Josh, I think this solution won't work if tomcat performs any redirects. This is the typical case for example in an application demanding a login. When the user is not authenticated the app will redirect to something like /login however tomcat will append the current context like in /context/login so at the end the context does show in the URL.
As you mentioned in your other question/response using just mod-jk plus tomcat virtual hosts is an option but there you will need to deploy your applications as ROOT.war which might not be that straightforward. There is a workaround so your application can be just dropped into tomcat webapps folder but as I described here the server will deploy the app at least twice.
It would be great if RewriteRule[P] plus JkOptions +ForwardURICompat could work but it doesn't. BTW I have tested this and I know mod_proxy does work as I proxied my site to cnn.com and I got their page under my site URL. Below are the logs BTW for the requests where you can see a proxy is being used:
127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/
127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK]
127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/login
127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/login [OK]
127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/j_spring_security_check
127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/j_spring_security_check [OK]
127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/
127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK]
I've been using this with great success:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(Context/.*)$
RewriteRule ^/(.*)$ /Context/$1 [P,L]
Notes on your situation:
You will need to get mod_proxy working or the [P] will be ignored and the request will be forwarded instead of proxied. There is no way around this.
+ForwardURICompat is part of mod_jk and will take effect after the rewriting.
mod_jk is ignoring the request because it never gets there. You need a RewriteCond (above) to prevent requests to /Context from being rewritten.
I'm currently looking for a way to do this without mod_rewrite and using, instead, just mod_jk and Tomcat <Host>'s. But I'm having trouble with apache, mod_jk and Tomcat hosts playing nicely together. The above should work fine for you.
I'll leave my original answer up but it is wrong. The proper way to do this would be with a Tomcat VirtualHost:
http://tomcat.apache.org/tomcat-6.0-doc/virtual-hosting-howto.html
The official walk-through in the link above is exactly what I've used several times now. I won't attempt to boil it down here.
The concept is the same as an Apache Vhost. Create a virtual host (eg. for something.yourtdomain.com) and deploy your webapp to the ROOT application (/) for that vhost and you're all set. This way, if you already have a ROOT webapp, you can have another at a different domain and the prior will remain unaffected.
As Nestor mentioned, an Apache rewrite rule will not handle things like tag libs and frameworks that automatically create links/form actions/etc for you based on the context root. In this case they will create the correct context root (/).
Following hints given by Nestor Urquiza's answer, i managed to solve the issue by defining additional Host in tomcat's server.xml because as said, the j_security_check request is answered by tomcat with a forward instruction to the browser which inevitably contains the context name so that users trying to login gets 408 errors. Therefore, a real passthrough inside Apache VirtualHost JkMount /* worker1 directive is achievable by making the intended context, a ROOT one.
The Apache httpd.conf [ and/or an included *.conf ] file :
<!-- the subdomain -->
<VirtualHost *:80>
ServerName appWelcome.example.org
ServerAlias www.appWelcome.example.org
JKMount /* worker1
</VirtualHost>
<!-- with mod_jk set up -->
LoadModule jk_module modules/mod_jk.so
JWorkersFile /etc/apache2/workers.properties
JkShmFile /var/log/apache2/mod_jk.shm
So to map all request made to subdomain http://appWelcome.example.org/ directly to the in-charge /appWelcome tomcat context, the appWelcome context must be addressable with request to http://appWelcome.example.org:8080/
So the tomcat server.xml file would then wear a separate Host for the app you are wiling to expose: .
<Server ...>
<Service>
<Engine defaultHost="localhost" ...>
<Host name="appWelcome.example.org" appBase="appWelcomeBase" ... >
<Valve ... />
</Host>
<Host name="localhost" appBase="webapps" ...>
<!-- this Host is typically shipped with manager, host-manager, docs,
sample, examples and a default ROOT context that shows tomcat default home. -->
<Valve ... />
</Host>
</Engine>
</Service>
</Server>
Note that the permissions ( and selinux context if enabled ) have to be adjust to mimic the default Host ones as follows :
$CATALINA_HOME/conf/Catalina/app.example.org as $CATALINA_HOME/conf/Catalina/localhost
$CATALINA_HOME/appWelcomeBase as $CATALINA_HOME/webapps
Whence this is done all that is left to do is issue rename and move the appWelcome.war web archive for it to auto-deploy in the created appBase ( replacing $CATALINA_HOME with its value, e.g. /var/www/tomcat7) :
# mv $CATALINA_HOME/webapps/appWelcome.war $CATALINA_HOME/appWelcomeBase/ROOT.war
Voila !
Use mod_proxy_ajp instead mod_jk like below:
<VirtualHost *:80>
ServerName domain.be
DocumentRoot /home/webapp/app/static/domain/
...
ProxyPass /Context ajp://localhost:8009/Context
ProxyPass / ajp://localhost:8009/Context/
...
</VirtualHost>