Apache + php-fpm : headers stripped? - apache

I had a PHP framework setup to use the php5_module for apache. The framework is custom written for a specific purpose and handles lots of things, for example the headers. On the new dev server there is a php-fpm instance setup and the old:
RewriteRule ^(.*)$ core.php
is replaced by ProxyPassMatch:
ProxyPassMatch ^(.*)$ unix:/tmp/php-fpm.sock|fcgi://127.0.0.1:9000/path/to/core.php
everything works great so far but it seems the headers that the php script adds are stripped or cause some kind of errors in the apache log.
Is it possible to use just the headers that the script adds and apache does not touch the headers at all?

That's just because you a saying that it's proxy server, which means for security reasons that's purged. as far as I can remember it's not really possible easily.
Anyway my suggestion is to use Nginx with PHP-FPM and if you need to use the Apache use the php module for apache as it's designed this way.
Hope it helped answering your question.

Related

How would you block all referring domains via .htaccess while allowing a certain one through. Not IP address. Script isn't working

I need to have a .htaccess file made to the following specifications.
Allow ONLY "exampledomain.com/sometext" to access "mydomain.com/folder"
Block all other referrers and redirect them to "google.com"
But I am not sure how to go about doing this.
So far this is what I have got. But it is not working.
<If "%{HTTP_HOST} != 'google.com'">
Redirect / http://www.yahoo.com/
</If>
Using the latest Apache. I really appreciate the help here. I have gone through a few other posts but can't seem to figure it out.
Does the 'google.com' have to include the full url or is their a way to make it be a wildcard like *google.com*?
This should point you into the right direction:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^mydomain\.com$
RewriteCond %{HTTP_REFERER} !^exampledomain\.com$
RewriteRule ^ https://www.google.com [R=301,END]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Apache 2.4 + PHP-FPM and Authorization headers

Summary:
Apache 2.4's mod_proxy does not seem to be passing the Authorization headers to PHP-FPM. Is there any way to fix this?
Long version:
I am running a server with Apache 2.4 and PHP-FPM. I am using APC for both opcode caching and user caching. As recommended by the Internet, I am using Apache 2.4's mod_proxy_fcgi to proxy the requests to FPM, like this:
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/foo/bar/$1
The setup works fine, except one thing: APC's bundled apc.php, used to monitor the status of APC does not allow me to log in (required for looking at user cache entries). When I click "User cache entries" to see the user cache, it asks me to log in, clicking on the login button displays the usual HTTP login form, but entering the correct login and password yields no success. This function is working perfectly when running with mod_php instead of mod_proxy + php-fpm.
After some googling I found that other people had the same issue and figured out that it was because Apache was not passing the Authorization HTTP headers to the external FastCgi process. Unfortunately I only found a fix for mod_fastcgi, which looked like this:
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
Is there an equivalent setting or some workaround which would also work with mod_proxy_fcgi?
Various Apache modules will strip the Authorization header, usually for "security reasons". They all have different obscure settings you can tweak to overrule this behaviour, but you'll need to determine exactly which module is to blame.
You can work around this issue by passing the header directly to PHP via the env:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
See also Zend Server Windows - Authorization header is not passed to PHP script
In some scenarios, even this won't work directly and you must also change your PHP code to access $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] rather than $_SERVER['HTTP_AUTHORIZATION']. See When setting environment variables in Apache RewriteRule directives, what causes the variable name to be prefixed with "REDIRECT_"?
This took me a long time to crack, since it's not documented under mod_proxy or mod_proxy_fcgi.
Add the following directive to your apache conf or .htaccess:
CGIPassAuth on
See here for details.
Recently I haven'd problem with this arch.
In my environement, the proxy to php-fpm was configured as follow:
<IfModule proxy_module>
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache2/htdocs/$1
ProxyTimeout 1800
</IfModule>
I fixed the issue set up the SetEnvIf directive as follow:
<IfModule proxy_module>
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache2/htdocs/$1
ProxyTimeout 1800
</IfModule>
I didn't find any similar settings with mod_proxy_fcgi BUT it just works for me by default. It asks for user authorization (.htaccess as usual) and the php gets it, and works like with mod_php or fastcgi and pass-header. I don't know if I was helpful...
EDIT:
it only works on teszt.com/ when using the DirectoryIndex... If i pass the php file name (even if the index.php!) it just doesn't work, don't pass the auth to the php. This is a blocker for me, but I don't want to downgrade to apache 2.2 (and mod_fastgi) so I migrate to nginx (on this machine too).

Apache caching urls, RewriteEngine causing problems

I was trying out the Apache Rewrite Engine, but was having problems because it cached it's responses. Now if I change the file, it does not do what the file says, but does what it did when I tried the same url before.
For example, I tried to type in
localhost/api
but I had not yet set a rule that would match that. The server gave me a 404 error. I tried to add a rule that would work with this url:
RewriteRule api/? api.php [L]
but it still gave me the same error. If I try an address like localhost/lapi which I didn't enter before I added the rule, it works. Is there a way to clear this cache and restart? I tried restarting apache using apachectl -k restart and apachectl -k graceful but I still had the same problem. Does anyone know how to fix this problem?
First of all, depending on the context of your rule, you may need a leading slash as in:
RewriteRule api/? /api.php [L]
Regarding the caching, do you have mod_cache enabled? If so, disable it and restart your server. mod_rewrite does not do any caching on its own. Also be sure to completely clear your browser cache and be aware that if you are not accessing your server over the same local network, there may be other caching taking place along the way.
This problem can also be caused by the MultiViews option, see Apache doc. Try omitting Option MultiViews from httpd.conf or add Options -MultiViews to .htaccess.
(The MultiViews option enables Apache to choose automaticaly between several versions of the file based on the file name extension and content preferences present in the HTTP request (i.e. something you probably don't want to happen). It can lead to this kind of bizzare failure when a rewrite rule just removes the script's extension.)

Authorization header missing in django rest_framework, is apache to blame?

I've managed to extend TokenAuthentication and I have a working model when using the request session to store my tokens, however when I attempt to pass Authorization as a header parameter as described here, I noticed that my Responses come back without the META variable HTTP_AUTHORIZATION. I also noticed that if I pass "Authorization2" as a header parameter that it is visible in the request:
{
'_content_type': '',
'accepted_media_type': 'application/json',
'_request': <WSGIRequest
path:/api/test_auth/,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{
'MOD_AUTH_CAS_S': 'ba90237b5b6a15017f8ca1d5ef0b95c1',
'csrftoken': 'VswgfoOGHQmbWpCXksGUycj94XlwBwMh',
'sessionid': 'de1f3a8eee48730dd34f6b4d41caa210'
},
META:{
'DOCUMENT_ROOT': '/etc/apache2/htdocs',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTPS': '1',
'HTTP_ACCEPT': '*/*',
'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
'HTTP_AUTHORIZATION2': 'Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4c',
...
My first guess is that the authorization header is being removed by apache, and I have read a few S/O questions that state that apache will throw out the value if it does not match basic authorization and authenticate, but I have no idea how to allow the Authorization header to 'pass through' to Django and the WSGIRequest. Does anyone know how to solve this problem?
I also use mod_auth_cas and mod_proxy, if that changes anything..
If you are using Apache and mod_wsgi, then I found the easy solution to this in the official Django REST framework website
Apache mod_wsgi specific configuration
Note that if deploying to Apache using mod_wsgi, the authorization header is not passed through to a WSGI application by default, as it is assumed that authentication will be handled by Apache, rather than at an application level.
If you are deploying to Apache, and using any non-session based authentication, you will need to explicitly configure mod_wsgi to pass the required headers through to the application. This can be done by specifying the WSGIPassAuthorization directive in the appropriate context and setting it to 'On'.
# this can go in either server config, virtual host, directory or .htaccess
WSGIPassAuthorization On
Sorry to answer my own question minutes after asking it. But it turns out it was apache2 after all! After crawling the webs and looking through a few search results I found this in a comment:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
Adding the above lines to my conf file seemed to solve all of my problems! Hopefully this helps users down the road!
It depends on which kind of Django/Apache deployment you did. You need to tell the correct Apache module to allow to pass "Authentication" HTTP header:
Apache/mod_wsgi:
WSGIPassAuthorization On
Apache/mod_fcgid:
FcgidPassHeader Authorization
In other words: many Apache modules filters "Authentication" HTTP header, so Django will not receive it. You have to be sure your Django App is receiving it in request.
See:
django_rest doc and Apache fcgid doc.
NOTE:
After modifying Apache configuration you'll need to restart apache daemon or tell to reload your .cgi file (i.e: touch my_site_fcgifile.fcgi).
The issue is the underscore in the HTTP header HTTP_AUTHORIZATION. Most webservers just ignores the headers with underscores.
Django dev server also exhibits the same, omitting headers with underscores.
This is the reason why Authorization2 works.
A Quick work around is to replace _ underscores in headers with - dashes,
Ex. changing the HTTP_AUTHORIZATION to HTTP-AUTHORIZATION

HTTP Authorization Rule in htaccess- convert to Nginx

I have recently moved my application from Apache to Nginx server. We have written
API's in Slim framework. So to enhance the basic security of API we have written token (static) based authentication(if-else loop) logic.
Below rule was added in .htaccess on the apache server which was working fine.
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
Now since we have moved to Nginx so above .htaccess rule will not work.
What changes do i need to make in Nginx config to get the above thing working.
It would be great if someone can explain the process step by step.
Thanks!
Try adding the following to your Nginx configuration.
fastcgi_pass_header Authorization;