I have some difficulties to understand the apache variables described in here:
https://httpd.apache.org/docs/2.4/expr.html#vars
What I need to use in my directive:
The IP of the webserver the apache is running on
The IP of the client trying to access the server
The URL (string) the client is trying to access
Alternatively, a boolean telling me whether the current request is coming from the server itself
As far as I understand, REMOTE_ADDR must be the client's IP. But where is the Servers ID hidden? SERVER_ADDR does not exist...
SERVER_ADDR depending if your server provide it, else try HTTP_HOST
REMOTE_ADDR
REQUEST_FILENAME/REQUEST_URI
There is no native function provided by Apache doing that but I let you check this topic you may find what you looking for.
Related
Hoping someone can give me some advice if possible.
We have a Linux box in our DMZ with the WebSphere plugin. This points to a Windows box running WebSphere Application Server.
httpd config only contains the default virtualhost with no ServerAlias specified. There is a redirect set up in the virtualhost in httpd.conf to forward any requests to service.domain.com to service.domain.com/wascontext1. Plugin-cfg.xml is set up with two uri groups, wascontext1 and wascontext2, but only 1 is actively used.
I want to use the Linux box as a reverse proxy for another application totally separate to WAS. It would have a different domain (i.e. dimsim.domain.com) but point to the same IP.
I was going to add another virtualhost for this but am unsure exactly how the WebSphere plugin will behave with it. From what I understand if I set this up and went to dimsim.domain.com/wascontext1 it would serve the WebSphere content as httpd forwards all requests to the plugin.
Is there a way to tell httpd to not send requests to the WebSphere plugin based on domain name or virtualhost? Or would doing a rewrite on any requests to dimsim.domain.com/wascontext be considered ok?
thanks
jc
EDIT: Thanks for the responses! I'll test changing the virtualhost name in plugin-cfg.xml on our second unused context and let you know how it goes.
A solution that doesn't require plugin-cfg.xml changes: If you use an Apache-based HTTP server, you can conditionally set the per-request variable "skipwas" to short-circuit the WAS Plugin processing.
e.g.
SetEnvIf Host ^dimsim\.domain\.com$ skipwas=1
If you look at the plugin-cfg.xml file, in the first part of the file you will find virtualhostgroup section similar to this:
<VirtualHostGroup Name="default_host">
<VirtualHost Name="*:9080"/>
<VirtualHost Name="*:9443"/>
<VirtualHost Name="*:443"/>
<VirtualHost Name="*:80"/>
</VirtualHostGroup>
just change the Name from * to the required domain name e.g. service.domain.com and then plugin will forward only requests for the service.domain.com hostname.
So something like:
<VirtualHost Name="service.domain.com:80"/>
should work for you.
When a request comes into the web server, it is passed to the WebSphere plugin and then plugin examines the request based on its configuration to determine if it should forward to WebSphere or pass back to the web server for further processing.
The "route" clauses in the plugin-cfg.xml are key to determining what will be forwarded and what will not. A request must match all the values in the route to be forwarded. A route contains virtual hosts, uris and clusters. The request must match one a virtual host from the VirtualHostGroup in the route, a URI from the UriGroup in the route and there must be an available server in the ServerCluster value of the route for the request to be sent to WebSphere.
Note-If you manipulate your plugin-cfg.xml for your setup, be aware that plugin is very sensitive about the format of this configuration and incorrect or invalid entries could cause a crash of the webserver. Be sure to backup the file and test before using in production. Also, if you modify your WebSphere configuration, it could overwrite this file and wipe out your changes.
Sorry for the late response.
covener's answer of setting the following does what I need.
SetEnvIf Host ^dimsim\.domain\.com$ skipwas=1
I have the following question that I do not know how to solve it in the most efficient way.
I have two servers, one with Apache where I have a Wordpress instance responding for port 80, and on another server I have a Wildfly with another application listening on port 8080. The Wordpress that I have configured on the Apache server, responds to the URL http://www.somedomain.com What I'm not so clear about is how to do when a request arrives at http://www.somedomain.com/yyyy and redirects me to the Wildfly server where an application is responding to the URL : 8080 / app
How could I do it in the most effective way? Using the rewrite module in the .htaccess file or using the Apache proxy module and configuring it in the Apache virtual host? How would I have to do it?
Thank you very much in advance.
You're mixing a few things that are not related to each other. First of all, a redirect is something different than a proxy. Redirecting means asking the client (browser) to look at another URL. A proxy, on the other hand, retrieves the content of the other URL itself and passes it to the client. Using a proxy, the other URL remains invisible to the client.
Second, mod_rewrite is not limited to htaccess configuration. In fact it's better to configure mod_rewrite in the virtual host configuration, just as you suggested with the proxy configuration.
The htaccess is simply for users who are not allowed to mess with the server configuration itself. Configuration in the htaccess can be limited by the admin for security purposes at the cost of slowing down the server.
That said, if you are looking to map your wildfly server paths into your main server's paths, you might want to use something like this inside your main server's virtual host block:
<Location "/yyyy">
ProxyPass "http://wildfly:8080/app"
</Location>
See http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypass for detailed explanations.
Trying to get shibboleth working on a Docker container, using Apache as a reverse proxy. Problems occur because I am using port 80 for the public Apache instance and port 8000 for the internal instance, which confuses shibboleth:
2017-10-03 07:34:23 ERROR OpenSAML.MessageDecoder.SAML2POST [5]: POST targeted at (https://dashboard.hpc.unimelb.edu.au/Shibboleth.sso/SAML2/POST), but delivered to (https://dashboard.hpc.unimelb.edu.au:8000/Shibboleth.sso/SAML2/POST)
The first URL is the external URL which the end user sees. The second URL is what the docker container sees when it gets the proxied request (with the HTTP host name forwarded).
Note I used "ShibURLScheme https" on the internal apache instance to ensure it believes https is being used, as the reverse proxy ensures all requests are https.
Is there anyway I call tell Shibboleth that this is OK, the URLs really are the same? Maybe by rewriting the URL shibboleth sees or something?
Thanks
There are two things I would check:
Make sure the ServerName directive in your Apache conf file is set to
https://dashboard.hpc.unimelb.edu.au:80. Notice the :80. Omitting
the port number completely may work too. You want Apache and vis-a-vis, shibd to see the ServerName that the client is using. You should also make sure you have a UseCanonicalName On directive as part of this.
This is likely less of a problem, but make sure your sp-metadata given to the IdP is correct. You should add entries for the FQDN(s) that the client sees. Please note that most of that documentation page isn't applicable to your scenario, but adding the correct metadata entries is vital.
It looks like your ServerName in Apache isn't correct, so I'd start there.
I have apache server on ubuntu 12.04 with virtual hosts and router forwarded 80 port to one of them. The directory is configured http-authentication. I need to provide authentication for the requests only when a request comes in the "outside", that is, only when the request comes through the external ip, and if I call from inside the network (or from the server at localhost), no authentication is required.
Thanks in advance for your help. Sorry for bad english.
You can use the allow from directive in conjunction with your http authentication directives in your httpd.conf file (or .htaccess file) to specify a range of IP addreses for which http authentication will not be required. See .htaccess / .htpasswd bypass if at a certain IP address for more info. Just specify your range of inside ip addresses in the allow from directive.
In a situation where Apache is sitting behind a reverse proxy (such as Squid), the cgi environment variable REMOTE_ADDR gets the address of the proxy rather than the client.
However, the proxy will set a header called X-Forwarded-For to contain the original IP address of the client so that Apache can see it.
The question is, how do we get Apache to replace REMOTE_ADDR with the value in the X-Forwarded-For header so that all of the web applications will transparently see the correct address?
You can use mod_rpaf for that. http://stderr.net/apache/rpaf/
Currently apache module mod_remoteip is the recommended way to do this; rpaf hasn't been reliably maintained, and can cause problems.
Note that the X-Forwarded-For header may contain a list of IP addresses if the request has traversed more than one proxy. In this case, you usually want the leftmost IP. You can extract this with a SetEnvIf:
SetEnvIf X-Forwarded-For "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" XFFCLIENTIP=$1
Note the use of $1 to set the XFFCLIENTIP environment variable to hold the contents of the first group in the regex (in the parentheses).
Then you can use the value of the environment variable to set headers (or use it in Apache log formats so that the logs contain the actual client IP).
In addition to mod_rpaf as mentioned before, it appears that mod_extract_forwarded will perform this function as well.
One advantage to mod_extract_forwarded is that it is available from EPEL for RHEL/CentOS servers whereas mod_rpaf is not.
It appears that neither of these two modules allow you to whitelist an entire subnet of proxy servers, which is why the CloudFlare folks created their own plugin: mod_cloudflare which, it should be noted, is not a general-purpose tool like the other two; it contains a hardcoded list of CloudFlare subnets.
Yes, we can do this.
Just add a auto_prepend_file in your PHP.ini like auto_prepend_file = "c:/prepend.php"
and in this file add this:
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
You need the MOD_REMOTEIP in apache width RemoteIPHeader X-Real-IP.
Cheers,
Guiremach
Since Apache 2.4 there is mod_remoteip built-in module that does this.
Enable mod_remoteip
(e.g. a2enmod remoteip)
Create a list of trusted IP ranges (the IPs from which you accept the remote IP header). You can put them in a file like conf/trusted-ranges.txt
Add this line to the Apache config:
RemoteIPTrustedProxyList conf/trusted-ranges.txt
Change your log file formats to use %a instead of %h for logging the client IP.
For Cloudflare you need to trust all their IP ranges and use a custom header CF-Connecting-IP:
RemoteIPHeader CF-Connecting-IP
You can get Cloudflare ranges like this:
curl https://www.cloudflare.com/ips-v4 > trusted-ranges.txt
curl https://www.cloudflare.com/ips-v6 >> trusted-ranges.txt
Unfortunately,
at the time of this writing, none of the backports and forks at freshports.org, people.apache.org or gist.github.com worked. They were all based on an early alpha version of apache httpd 2.3 which was neither compatible with current versions of 2.2 nor 2.4.
So after hours of wasting time while trying to adjust the backports to create a real working one for httpd 2.2, I decided to move to httpd 2.4. Within httpd 2.4, mod_remoteip works smoothly, even if a load balancer has permanent keepalive connections which it uses to proxy requests from different actual client ip addresses to the backend. I'm not sure if the other modules can handle this situation (changing client ip addresses on each request within the same connection).
Remember that this value can be spoofed. See http://blog.c22.cc/2011/04/22/surveymonkey-ip-spoofing/ for a real-life example with Cross-site Scripting consequences.
You can install the module mod_extract_forwarded and set MEFaccept parameter to all.