Use apache mod_mem_cache to cache Rest services - apache

Behind Apache 2.2 httpd server, i have a java REST-based application with this kind of service :
GET /countries/canada
I'd like to enable mod_mem_cache to speed up these services like that :
CacheEnable mem /countries/*
Is it possible to use wildcard ?
If not, what is there any solution to do that ?

In fact, we don't need wildcard.
For example, if a defined the following configuration :
ProxyPass /jsontest/ http://echo.jsontest.com/
ProxyPassReverse /jsontest/ http://echo.jsontest.com/
<IfModule mod_cache.c>
<IfModule mod_mem_cache.c>
CacheEnable mem /jsontest/
CacheDefaultExpire 300
MCacheSize 1024000
MCacheMaxObjectCount 10000
MCacheMinObjectSize 1
MCacheMaxObjectSize 2048000
CacheStorePrivate On
CacheIgnoreNoLastMod On
CacheStoreNoStore On
CacheIgnoreCacheControl On
</IfModule>
</IfModule>
I can request :
http://localhost/jsontest/
or
http://localhost/jsontest/titi/tutu
and apache will store each response and serve them :
Incoming request is asking for an uncached version of /jsontest/, but we have been configured to ignore it and serve cached content anyway
mem_cache: Cached url: http://localhost:80/jsontest/?
Incoming request is asking for an uncached version of /jsontest/, but we have been configured to ignore it and serve cached content anyway
mod_cache.c(312): cache: serving /jsontest/
Incoming request is asking for an uncached version of /jsontest/titi/tutu, but we have been configured to ignore it and serve cached content anyway
mod_cache.c(753): cache: Caching url: /jsontest/titi/tutu
Incoming request is asking for an uncached version of /jsontest/titi/tutu, but we have been configured to ignore it and serve cached content anyway
mod_cache.c(312): cache: serving /jsontest/titi/tutu
Be carefull :
With CacheStorePrivate, CacheIgnoreNoLastMod, CacheStoreNoStore and CacheIgnoreCacheControl, i disabled all default behavior and force cache !!!
You have to ask yourself if it is your requirement.

Related

How to disable Apache HTTP Header info in AWS Load Balancer Response?

I have a node.js environment deployed using AWS Elastic Beanstalk on an Apache server. I have run a PCI scan on the environment and I'm getting 2 failures:
Apache ServerTokens Information Disclosure
Web Server HTTP Header Information Disclosure
Naturally I'm thinking I need to update the httpd.conf file with the following:
ServerSignature Off
ServerTokens Prod
However, given the nature of Elastic Beanstalk and Elastic Load Balancers, as soon as the environment scales, adds new servers, reboots etc the instance config will be overwritten.
I have also tried putting the following into an .htaccess file:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
# Security hardening for PCI
Options -Indexes
ServerSignature Off
# Dissallow iFrame usage outside of loylap.com for PCI Security Scan
Header set X-Frame-Options SAMEORIGIN
On the node js side I use the "helmet" package to apply some security measures, I also use the "express-force-https" package to ensure the application is enforcing https. However, these only seem to be taking effect after the Express application is initiated and after the redirect.
I have Elastic Load Balancer listeners set up for both HTTP (port 80) and HTTPS (port 443), however the HTTP requests are immediately routed to HTTPS.
When I run the following curl command:
curl -I https://myenvironment.com --head
I get an acceptable response with the following line:
Server: Apache
However when I run the same request on the http endpoint (i.e. before redirects etc):
curl -I http://myenvironment.com --head
I get a response that discloses more information about my server than it should, and hence the PCI failure:
Server: Apache/2.4.34 (Amazon)
How can I force my environment to restrict the http header response on HTTP as well as HTTPS?
Credit to #stdunbar for leading me to the correct solution here using ebextensions.
The solution worked for me as follows:
Create a file in the project root called .ebextensions/01_server_hardening.config
Add the following content to the file:
files:
"/etc/httpd/conf.d/03_server_hardening.conf":
mode: "000644"
owner: root
group: root
content: |
ServerSignature Off
ServerTokens Prod
container_commands:
01_reload_httpd:
command: "sudo service httpd reload"
(Note: the indentation is important in this YAML file - 2 spaces rather than tabs in the above code).
During elastic beanstalk deployment, that will create a new conf file in /etc/httpd/conf.d folder which is set up to extend the httpd.conf settings in ELB by default.
The content manually turns off the ServerSignature and sets the ServerTokens to Prod, achieving the PCI standard.
Running the container command forces a httpd reboot (for this particular version of Amazon linux - ubuntu and other versions would require their own standard reload).
After deploying the new commands to my EB environment, my curl commands run as expected on HTTP and HTTPS.
An easier and better solution exists now.
The folder /etc/httpd/conf.d/elasticbeanstalk is deleted when the built-in application server is restarted (e.g. when using EB with built-in Tomcat). Since .ebextensions are not re-run the above solution stop working.
This is only the case when the application server is restarted (through e.g. Lambda or the Elastic Beanstalk web-console). If the EC2 instance is restarted this is not an issue.
The solution is to place a .conf file in a sub-folder in the .ebextensions.
.ebextensions
httpd
conf.d
name_of_your_choosing.conf
Content of the file is the same as the output of the .ebextensions above, e.g.
ServerSignature Off
ServerTokens Prod
This solution will survive a restart of the application server and is much easier to create and manage.
You will ultimately need to implement some ebextensions to have this change applied to each of your Beanstalk instances. This is a mechanism that allows you to create one or more files that are run during the initialization of the beanstalk. I have an older one that I have not tested in your exact situation but it does the HTTP->HTTPS rewrite like you're showing. It was used in the Tomcat Elastic Beanstalk type - different environments may use different configurations. Mine looks like:
files:
"/tmp/00_application.conf":
mode: "000644"
owner: root
group: root
content: |
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
</VirtualHost>
container_commands:
01_enable_rewrite:
command: "echo 'LoadModule rewrite_module modules/mod_rewrite.so' >> /etc/httpd/conf/httpd.conf"
02_cp_application_conf:
command: "cp /tmp/00_application.conf /etc/httpd/conf.d/elasticbeanstalk/00_application.conf"
Again, this is a bit older and has not been tested for your exact use case but hopefully it can get you started.
This will need to be packaged with your deployment - i.e. in Java a .jar or .war or a .zip in other environments. Take a look at the documentation link to learn more about deployments.
There is a little change in configuration file path as AWS has introduced Amazon Linux 2
.ebextentions
.platform
httpd
conf.d
whateverFilenameyouwant.conf
in .platform/httpd/conf.d/whatever-File-NameYouWant.conf
add below two line
ServerSignature Off
ServerTokens Prod
Above is for Apache
Since AWS by default uses nginx for reverse proxy
replace httpd to nginx it should work

Apache 2.4 mod_cache + mod_cache_disk + modjk: 304 Not Modified, but Content-Length modified

I am getting crazy with mod_cache!
My current setup:
Apache 2.4 on Ubuntu with:
- mpm_worker
- mod_jk
- mod_cache
- mod_cache_disk
- mod_expires
- mod_deflate
HTTP & HTTPS Request are balanced by modjk to 5 Tomcat AppServers.
I want to cache media assets served by Tomcat Instances, but getting trouble with mod_cache.
My current cache configuration:
CacheRoot /srv/volatile/cache
CacheDirLevels 3
CacheDirLength 2
CacheEnable disk /medias
# Currently active:
CacheQuickHandler off
CacheLock on
CacheLockPath /tmp/mod_cache-lock
CacheLockMaxAge 5
CacheIgnoreHeaders Set-Cookie
# This is another configuration i tried:
#CacheIgnoreNoLastMod On
#CacheIgnoreCacheControl On
#CacheIgnoreQueryString On
#CacheIgnoreHeaders Set-Cookie
I checked a lot of tutorials und guides, but without success.
The first request is getting served fine by Apache, following request are failing with weird errors:
Recalled cached URL info header https://...
Recalled headers for URL https://...
Adding CACHE_SAVE filter for /medias...
Adding CACHE_REMOVE_URL filter for /medias...
cache: /media... responded with an uncacheable 304, retrying the request. Reason: contradiction: 304 Not Modified, but Content-Length modified
cache: Removing url https://
Deleting /srv/volatile/cache/.../.header from cache.
Deleting /srv/volatile/cache/.../.data from cache.
Deleting directory /srv/volatile/cache/.../7n from cache.
URL https://... failed the size check (0 < 1)
I thought that it could be a load balancing issue, because of walk threw multiple nodes or something like that, but the behavior isn't deterministic. Tests with apache-bench & jmeter showed me that 60-70% of request failed, so that not exactly every X request failed.
If the CacheIgnoreCacheControl On option is set, requests threw jmeter & apache-bench didn't fail, but access threw Browser failed.
Someone any idea ?
Thanks
Taulant
I think, this is covered by mod_cache bug 56881, which is fixed in Apache 2.4.11.

Making Apache faster by adjusting KeepAlive, MaxClients and AllowOverride

I'm trying to configure apache to react faster. Currently I experience heavy lags and huge response times. When I googled for answers, there were articles mentioning KeepAlive, MaxClients and AllowOverride so my focus is on them for now, I guess. I just don't seem to find them.
Here is a the phpinfo(); output:
apache2handler
**************
Apache Version Apache/2.4.12 (Win64) PHP/5.6.8
Apache API Version 20120211
Server Administrator admin#example.com
Hostname:Port
Max Requests Per Child: 0 - Keep Alive: on - Max Per Connection: 100
Timeouts Connection: 60 - Keep-Alive: 5
Virtual Server No
Server Root C:/Apache24
Loaded Modules core mod_win32 mpm_winnt http_core mod_so mod_access_compat
mod_actions mod_alias mod_allowmethods mod_asis mod_auth_basic mod_authn_core mod_authn_file
mod_authz_core mod_authz_groupfile mod_authz_host mod_authz_user mod_autoindex mod_cgi
mod_dir mod_env mod_include mod_isapi mod_log_config mod_mime mod_negotiation mod_php5
mod_rewrite mod_setenvif
Directive Local Value Master Value
engine 1 1
last_modified 0 0
xbithack 0 0
Maybe somebody can explain this output to me? I particular:
"Timeouts" = "Connection: 60" setting
"Per Child" = "0" setting
If I understand this right:
there are 60 connections to be allowed
simultaneously
every connection has a maximum of 100 requests (why
so many?)
the server allows a client to load all the ressources
in one request for 5 seconds
maybe those settings are to be found in httpd.conf and not in php.ini? (right now I don't have access to those files)
As far as I know the Timeouts relates to how longer the server will wait for connection, with 60 seconds being the default.
The Per Child bit has to do with how many threads your running per child process.
I'm a bit vague on this stuff but have a read through the docs and you should find all the explainations you need!

Best Apache Configuration

Please, Can you help me for best Apache Configuration
I own the servers for files download, Download files by direct links
ex: domain.com/files.rar
Without programming or php function
The problem: Sometimes I having a high load or stop servers
For this can you help me for best Apache Configuration
Such as:
Server Limit
Max Clients
Max Requests Per Child
Keep-Alive
Keep-Alive Timeout
Max Keep-Alive Requests
Etc.
My servers with 4GB RAM and HDD drives, and 100Mb-ps and 1GBMb-ps
Thanks.
Separate Static and Dynamic Content
Use separate servers for static and dynamic content. Apache processes serving dynamic content will carry overhead and swell to the size of the content being served, never decreasing in size. Each process will incur the size of any loaded PHP or Perl libraries. A 6MB-30MB process size [or 10% of server's memory] is not unusual, and becomes a waist of resources for serving static content.
For a more efficient use of system memory, either use mod_proxy to pass specific requests onto another Apache Server, or use a lightweight server to handle static requests:
Nginx
lighttpd
Or use a front-end caching proxy such as Squid-Cache or Varnish-Cache
The Server handling the static content goes up front.
Note that configuration settings will be quite different between a dynamic content Server and a static content Server.
mod_deflate
Reduce bandwidth by 75% and improve response time by using mod_deflate.
LoadModule deflate_module modules/mod_deflate.so
<Location />
AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml application/x-javascript
</Location>
Loaded Modules
Reduce memory footprint by loading only the required modules.
Some also advise to statically compile in the needed modules, over building DSOs (Dynamic Shared Objects). Very bad advice. You will need to manually rebuild Apache every time a new version or security advisory for a module is put out, creating more work, more build related headaches, and more downtime.
mod_expires
Include mod_expires for the ability to set expiration dates for specific content; utilizing the 'If-Modified-Since' header cache control sent by the user's browser/proxy. Will save bandwidth and drastically speed up your site for [repeat] visitors.
Note that this can also be implemented with mod_headers.
KeepAlive
Enable HTTP persistent connections to improve latency times and reduce server load significantly [25% of original load is not uncommon].
prefork MPM:
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 100
worker and winnt MPMs:
KeepAlive On
KeepAliveTimeout 15
MaxKeepAliveRequests 100
With the prefork MPM, it is recommended to set 'KeepAlive' to 'Off'. Otherwise, a client will tie up an entire process for that span of time. Though in my experience, it is more useful to simply set the 'KeepAliveTimeout' value to something very low [2 seconds seems to be the ideal value]. This is not a problem with the worker MPM [thread-based], or under Windows [which only has the thread-based winnt MPM].
With the worker and winnt MPMs, the default 15 second timeout is setup to keep the connection open for the next page request; to better handle a client going from link to link. Check logs to see how long a client remains on each page before moving on to another link. Set value appropriately [do not set higher than 60 seconds].
SymLinks
Make sure 'Options +FollowSymLinks -SymLinksIfOwnerMatch' is set for all directories. Otherwise, Apache will issue an extra system call per filename component to substantiate that the filename is NOT a symlink; and more system calls to match an owner.
<Directory />
Options FollowSymLinks
</Directory>
AllowOverride
Set a default 'AllowOverride None' for your filesystem. Otherwise, for a given URL to path translation, Apache will attempt to detect an .htaccess file under every directory level of the given path.
<Directory />
AllowOverride None
</Directory>
ExtendedStatus
If mod_status is included, make sure that directive 'ExtendedStatus' is set to 'Off'. Otherwise, Apache will issue several extra time-related system calls on every request made.
ExtendedStatus Off
Timeout
Lower the amount of time the server will wait before failing a request.
Timeout 45
If you are having load-problems with your apache setup, you could also consider migrating to another system. From my personal experience I would suggest you to try nginx to serve static files.

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).