ELB health check for redirect endpoint - apache

I have a web application running on Apache2 (2.4)
and i am redirecting the homepage and entire website (/*) to another url, kind of auth and then returns back to the homepage
So in my apache2 location directive
...
<Location "/">
AuthType AuthAgent
Require valid-user
Satisfy any
</Location>
...
So know ELB is failing health check because the homepage is being used as endpoint for health check.
How do i do it so that ELB passes healthcehck when the redirection happens. Redirection is 302
I just want ELB to say pass on 302 or however i can make the healthcheck pass
Thanks

Classic ELB will only consider a 200 response as a success. Everything else is a health check failure (including a 302).
Source: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-healthchecks.html (see under "Ping Path")
You have 2 options:
Option 1: Switch to use an Application Load Balancer instead. By doing this, you can configure it to accept 302 as a health check success.
Option 2: Add a non-redirect URL to your web server specifically for the health check. So you would have something like /healthcheck.html return a 200 success and everything else return a redirect 302.

Here is what i did to solve the issue PERFECTLY!
i added regex to the location directive so that it redirects all except some URL i dont want to redirect
...
<Location ~ "^((?!/status).)*$">
AuthType AuthAgent
Require valid-user
Satisfy any
</Location>
...
so it redirects everything except /status/

Related

Apache - deny non-local requests that match a specific URL pattern

I need to configure my Apache (2.4) in a way, that it prevents answering specific requests
I have an application that runs on a server myapplication.com.
Browsing the application triggers some further ajax requests on the server, having the pattern myapplication.com/abc. These kind of "abc"-requests must be prohibited, when being called from a different context then this one. Thus, is should not be possible to call this request in a different tab. Neither should it be possible to call these requests outside a browser context, for example via curl or wget or any non-browser http client.
The directive must look something like this
<If "Request has not been triggered as ajax from within my application" && %{REQUEST_URL} contains 'abc' ">
Require all denied
</If>
This directive causes an error and I dont know why, changing =~ to !~ is semantically false but does not cause an error.
<If "%{HTTP_REFERER} !~ /myapplication.com/ && %{QUERY_STRING} =~ /abc/ ">
Require all denied
</If>
What can be wrong with that?
Any help debugging the apache config would also be appreciated - I don't get any information why this directive causes errors.
Any XMLHttpRequest or fetch call made from myapplication.com in browser will contain myapplication.com as referer header.
The following apache conf snippet will block requests which referrer isn't myapplication.com.
<Location "/abc">
RewriteEngine on
RewriteCond "%{HTTP_REFERER}" "!myapplication.com"
RewriteRule . - [R=403,L]
</Location>
This configuration requires mod_rewrite which can be enabled with a2enmod rewrite if not already done.

Apache redirect location from new server to old

www.old-server.com/ws/ is the base URL for a web service on old-server. This is accomplished using a Location directive for "/ws" with a setHandler enclosed within the directive.
when a request for www.new-server.com/ws/ is received new-server needs to redirect the request to old-server/ws/. Any trailing parts of request URL need to be passed to old-server as well.
Running Apache2, with mod_rewrite.so loaded, on CentOS 7.
on new-server, the following does not work.
<Virtual Hosts>
...
<Location /ws>
Redirect "https://www.old-server/ $1"
</Location>
...
</Virtual Hosts>
I think the doc's say Redirect is not support inside of Location.
What is the correct way to do redirect the request URL to old-server?
The answer for me was to stop over thinking the problem. The Location directive is fine, but my redirect statement was wrong. The following is working at the moment, pending further testing with more complex scenarios.
<Virtual Hosts>
...
<Location /ws>
Redirect "/ws" "https://www.old-server/ws"
</Location>
...
</Virtual Hosts>

Apache Conditional Redirect Rule not forwarding header values

Goal:
To perform conditional redirect/forward from Site1 to Site2 based on specific header (HTTP_SM_USER) value of the request (in Site1) and ensure all the current custom header data is forwarded as part of the redirect/forward to Site2. The user can see the url change in the browser window after the redirect.
Flow:
User accesses Site 1 --> External Application Sets few custom headers in addition to default HTTP headers based on certain criteria --> Web-server looks for specific header value and if matches redirect all the headers to Site 2.
Apache Web server Config:
<VirtualHost *.443>
ServerName site1.com
ServerAdmin ashish#test.com
UseCanonicalName on
DocumentRoot /var/www/html
#
# SSL Config comes here
#
ErrorLog /path/to/error/log
TransferLog /path/to/access/log
LogLevel warn
RewriteEngine On
RewriteCond %{HTTP:SM_USER} ^USER1$ [NC]
RewriteRule .* https://site2.com/$1 [R=301, L]
<Location /page1>
.
.
</Location>
.
.
.
</VirtualHost>
Question: The Conditional Redirect happens but the headers are lost. What should I do to ensure the HTTP headers are forwarded as well ? I tried to see into apache mod_proxy but wasn't sure how in this scenario to use it. Experts please help. Any alternative suggestions are welcome too.
Solution:
I finally got it to work (with mod_proxy) after a lot of troubleshooting using the below flags and proxy rules. All Rewrite rules were removed.
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
ProxyPass "/" "https://site2.com/" Keepalive=On
ProxyPassReverse "/" "https://site2.com/"
Note: User accesses Site 1 -> External app sets headers and apache immediately proxies to Site 2. Headers are now available on Site2.
You can't have the redirect "forward" headers, because it is up to the client what it sends to the next server after it has been issued a redirect. It may choose not to follow the redirect at all! Unlikely but just to make it clear what the situation is.
If you want the URL to change in the browser, then you need to do this on the application side. Have your application handle directing to the next server, and just issue a 200 response with an instruction for it to do so. Then it can send the custom headers as it did with the first request.
If that is not acceptable, then using mod_proxy could work as you said, but it would not change the URL in the browser, because the first server would be proxying the request to the second, so the browser would still see it as being the first.
In summary, you cannot do what you want to do, because HTTP does not work that way, so you are going to have to compromise in some way, either by not changing the URL in the browser, or by updating the application to take care of it.

Reverse proxy with request dispatch (to Rstudio server)

I have a multi-tier application of three layers lets say public, business and workspace (all running apache).
Client requests hits the public servers, requests are processed and dispatched on to business servers that does 'things' and response is returned back to public server which then processes the response and pass it on to the client.
I have a scenario wherein I want a request say /rstudio coming to the public server dispatched onto the business which intern reverse proxy to workspace server. There are two catch here:
the workspace server varies per request
application running on workspace server (Rstudio) uses GWT and references resources (static resources js, css etc and RPC coms) on the root url. All the in-application redirection also happens on the domain.
From the business server, I have setup reverse proxy to Rstudio server from my application server.
<Proxy *>
Allow from localhost
</Proxy>
ProxyPass /rstudio/ http://business_server/
ProxyPassReverse /rstudio/ http://business_server/
RedirectMatch permanent ^/rstudio$ /rstudio/
and this work fine (ref. https://support.rstudio.com/hc/en-us/articles/200552326-Running-with-a-Proxy). To handle dynamic workspace server, I could the following but ProxyPassReverse does not support expression in value and this no joy with this approach.
ProxyPassMatch ^/rstudio/(.*)$ http://$1
ProxyPassReverse ^/rstudio/(.*)$ http://$1
RedirectMatch permanent ^/rstudio$ /rstudio/
I have tried the same with mod_rewrite rule (following) but without ProxyPassReverse and due to domain redirection on the GWT Rstudio, this does not work. Adding ProxyPassReverse would fix the problem but I am caught up with no expression on value part to deal with dynamic workspace server issue.
RewriteRule "^/rstudio/(.*)" "http://$1" [P]
Following is the third approach to solve this problem using LocationMatch and mod_headers:
<LocationMatch ^/rstudio/(.+)>
ProxyPassMatch http://$1
Header edit Location ^http:// "http://%{SERVER_NAME}e/rstudio/"
</LocationMatch>
But this is no joy too because value on header directive is not evaluated against environment variable (and only back-references work here). Althought I can get the reverse proxy thing working if I had code the business_server, which is :
<LocationMatch ^/rstudio/(.+)>
ProxyPassMatch http://$1
Header edit Location ^http:// "http://private_server/rstudio/"
</LocationMatch>
Question 1: I was wondering if there are any better way to solve this problem without hardcoding the server DNS in apache conf?
Question 2: With the hard coded server DNS the reverse proxy works for me (patchy but works) but I am hit with GWT issue of resource references on root and the request dispatch is not fully working. I get to the signin page but resources are not found.
I was wondering if there is any better way to handle that?
Following is the example log from browser:
Navigated to https://public_server/rstudio
rworkspaces:43 GET https://public_server/rstudio.css
rworkspaces:108 GET https://public_server/js/encrypt.min.js
rworkspaces:167 GET https://public_server/images/rstudio.png 404 (Not Found)
rworkspaces:218 GET https://public_server/images/buttonLeft.png 404 (Not Found)
rworkspaces:218 GET https://public_server/images/buttonTile.png 404 (Not Found)
rworkspaces:218 GET https://public_server/images/buttonRight.png 404 (Not Found)

Nexus sonatype apache 2.4 proxy does not allow admin login

I have just setup nexus 2.8.1 and a reverse proxy via the following directives in an Apache 2.4 configuration.
<Location /nexus>
RequestHeader unset Authorization
ProxyPreserveHost On
ProxyPass http://nexushost.server:8082/nexus
ProxyPassReverse http://nexushost.server:8082/nexus
RequestHeader set X-Forwarded-Proto "https"
</Location>
However, whenever I try to login it always fails with a invalid username/password or access to ui not enabled.
If I try the same access by going directly to the http://nexushost.server:8080/nexus page then I don't have any issues logging in with the same credentials.
Has anyone else experienced a similar issue.
You have to map cookies to be passed through as well as a few other things. Check out the documentation in the Nexus book.
http://books.sonatype.com/nexus-book/reference/install-sect-proxy.html
Specifically the cookies are required for the UI to work in a browser.
I believe your problem comes from this directive:
RequestHeader unset Authorization
I guess you're doing that because you're using Basic auth in your Apache and you don't want the Authorization header to drift unto Nexus. Unfortunately Nexus uses the same header to perform authentication (you can verify this by opening the network analyzer of your browser).
I came up with the following strategies:
You perform basic auth in Apache and disable auth in Nexus, by giving anonymous all the rights for example. For obvious security reasons, you must make sure that Nexus is bound to 127.0.0.1 and not 0.0.0.0.
You disable basic auth in Apache (plus of course removing the above directive) and let Nexus perform the authentication.
You map your Apache user/passwords to those of Nexus. You'll need to remove the above directive to let the Authorization header propagate to Nexus. This gives you the advantage of not showing Nexus at all for unauthenticated users, while retaining the right management of Nexus. The only drawback is that you need to manage passwords in 2 places.
Same as 3 but to workaround the password management overhead, you set in nexus the same password for all your users (e.g 'nexus_password') then you make Apache rewrite the authorization header with this password. Here is an example of Apache configuration that does it:
RewriteEngine On
RewriteMap base64map prg:/usr/bin/b64
<Location />
RewriteCond %{REMOTE_USER} (.*)
RewriteRule .* - [E=R_U:${base64map:%1:nexus_password}]
RequestHeader set Authorization "Basic %{R_U}e"
</Location>
With /usr/bin/b64 wrapping around base64:
#!/bin/bash
# MANAGED BY PUPPET
# This is an apache RewriteMap interface for base64 : apache runs this program only once at startup
# See http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewritemap
while read line; do
echo -n $line | /usr/bin/base64
done;
Same as 1, make sure Nexus is bound to localhost.