Tuesday, April 12, 2011

Force yum update Command To Exclude Certain Packages

SkyHi @ Tuesday, April 12, 2011
Q. How can I exclude selected packages when I rum yum update command under CentOS Linux server?

A. Yum uses a configuration file at /etc/yum/yum.conf or /etc/yum.conf. You need to place exclude directive to define list of packages to exclude from updates or installs. This should be a space separated list. Shell globs using wildcards * and ?) are allowed.
How do I exclude php and kernel packages when I use "yum update"?

Open /etc/yum.conf file:
# vi /etc/yum.conf
Append following line under [main] section, enter:
exclude=php* kernel*
At the end, it should look like as follows:

[main]
cachedir=/var/cache/yum
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
exclude=php* kernel*

# Note: yum-RHN-plugin doesn't honor this.
metadata_expire=1h

# Default.
# installonly_limit = 3

# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d

yum --exclude command line option

Finally, you can skip yum command updates on command line itself using following syntax:
# yum --exclude=package* update
# yum --exclude=php* update
# yum --exclude=kernel* update


REFERENCES
http://www.cyberciti.biz/faq/redhat-centos-linux-yum-update-exclude-packages/

Getting yum updates by E-mail

SkyHi @ Tuesday, April 12, 2011
I run several CentOS 4.0 servers, and having to manually check each server for new updates is tedious. To simplify my life, I decided to write a shell script (yumnotifier) to E-mail me when new updates are available. The script (yumnotifier) analyzes the output from ‘yum check-update,’ and generates an E-mail similar to the following if updates are available:

From root@localhost.localdomain Sat Jul 15 19:24:59 2006
Date: Sat, 15 Jul 2006 19:24:59 -0400
From: root
To: matty@localhost.localdomain
Subject: Updates available for biscuit

==== The following updates are available for biscuit ===

comps.i386 2:4.3CENTOS-0.20060314 base
gtk2.i386 2.4.13-18 base
kernel.i686 2.6.9-34.0.2.EL update
libtiff.i386 3.6.1-10 update
mysql.i386 4.1.20-1.RHEL4.1 update
mysql-devel.i386 4.1.20-1.RHEL4.1 update

If you manage systems that use yum, you might be interested in this script.

#!/bin/sh 
#
# Program: E-mail available yum updates <yumnotifier>
#
# Author: Matty < matty91 at gmail dot com >
#
# Current Version: 1.2
#
# Revision History:
#
#  Version 1.2
#    - Removed ! from if statement - John Beaman
#    - Changed comments to reference "yumnotifier", not
#      "yumupdate" -- John Beaman
#
#  Version 1.1
#    - Switched test statement to use "-s" - Luca Rozza
#
#  Version 1.0
#    Initial Release
#
# Last Updated: 10-24-2007
#
# Purpose:
#   yumnotifier checks for updated software package, and E-mails the
#   address defined in the ${ADMIN} variable if updates are available.
#
# License:
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Installation:
#   Copy the shell script to a suitable location
#
# Usage:
#   To check for new updates each day at midnight, a cron job similar to the
#   following can be used:
#
#   $ crontab -l | grep yumnotifier
#   0 0 * * * /etc/scripts/yumnotifier
#
# Sample output
#   An E-mail similar to the following is sent if updates are available:
#
#   From root@localhost.localdomain  Sat Jul 15 19:24:59 2006
#   Date: Sat, 15 Jul 2006 19:24:59 -0400
#   From: root <root@localhost.localdomain>
#   To: matty@localhost.localdomain
#   Subject: Updates available for biscuit
#  
#   ==== The following updates are available for biscuit ===
#  
#   comps.i386                               2:4.3CENTOS-0.20060314 base            
#   gtk2.i386                                2.4.13-18              base            
#   kernel.i686                              2.6.9-34.0.2.EL        update          
#   libtiff.i386                             3.6.1-10               update          
#   mysql.i386                               4.1.20-1.RHEL4.1       update          
#   mysql-devel.i386                         4.1.20-1.RHEL4.1       update          
#   newt.i386                                0.51.6-7.rhel4         base            
#   php.i386                                 4.3.9-3.15             update          
#   php-ldap.i386                            4.3.9-3.15             update          
#   php-pear.i386                            4.3.9-3.15             update          
#   postgresql-libs.i386                     7.4.13-2.RHEL4.1       update          
#   rpmdb-CentOS.i386                        2:4.3-0.20060314       base            
#   sendmail.i386                            8.13.1-3.RHEL4.5       update          
#   sendmail-cf.i386                         8.13.1-3.RHEL4.5       update          
#   spamassassin.i386                        3.0.6-1.el4            update          
#   vixie-cron.i386                          4:4.1-44.EL4           update          
#   xorg-x11-Mesa-libGL.i386                 6.8.2-1.EL.13.25.1     update          
#   xorg-x11-font-utils.i386                 6.8.2-1.EL.13.25.1     update          
#   xorg-x11-libs.i386                       6.8.2-1.EL.13.25.1     update          
#   xorg-x11-xauth.i386                      6.8.2-1.EL.13.25.1     update          
#   xorg-x11-xfs.i386                        6.8.2-1.EL.13.25.1     update        

PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH

# Locations of binaries
GREP="/bin/grep"
HOST=`hostname`
MAIL="/bin/mail"
MKTEMP="/bin/mktemp"
YUM="/usr/bin/yum"

# Who to E-mail with new updates
ADMIN="matty"

if [ ! -f ${YUM} ]
then
        echo "Cannot find ${YUM}"
        exit 1
fi

if [ ! -f ${MKTEMP} ]
then
        echo "Cannot find ${MKTEMP}"
        exit 1
fi

if [ ! -f ${MAIL} ]
then
        echo "Cannot find ${MAIL}"
        exit 1
fi

if [ ! -f ${GREP} ]
then
        echo "Cannot find ${GREP}"
        exit 1
fi

# Dump the yum results to a safe working file
WORK=`${MKTEMP} /tmp/yum.results.XXXXXX`

${YUM} -e0 -d0 check-update > ${WORK}

# If there are updates available, E-mail them
if [ -s ${WORK} ]
then
        REPORT=`${MKTEMP} /tmp/yum.report.XXXXXX`
        echo "==== The following updates are available for ${HOST} ===" > ${REPORT}
        cat ${WORK} >> ${REPORT}
        cat ${REPORT} | ${MAIL} -s "Updates available for ${HOST}" ${ADMIN}
fi

# Cleanup temporary files
rm ${REPORT} ${WORK}



Great script – much better than my last attempt to do this. I made a small change to ignore kernel updates and only send an email if the return code for yum check-update is not zero:

${YUM} -e0 -d0 check-update –exclude=kernel* > ${WORK}

# If there are updates available, E-mail them
if [ $? -ne "0" ]
then
REPORT=`${MKTEMP} /tmp/yum.report.XXXXXX`
echo “==== The following updates are available for ${HOST} ===” > ${REPORT}
cat ${WORK} >> ${REPORT}
cat ${REPORT} | ${MAIL} -s “Updates available for ${HOST}” ${ADMIN}

REFERENCES
http://prefetch.net/blog/index.php/2006/07/16/getting-yum-updates-by-e-mail/
http://prefetch.net/code/yumnotifier

Friday, April 8, 2011

Setting up PHP-FastCGI and nginx? Don’t trust the tutorials: check your configuration!

SkyHi @ Friday, April 08, 2011
Summary

Several days ago, I had to deal with a compromised web application: an attacker had somehow managed to upload PHP backdoor scripts onto the application’s server. Thanks to some log file sleuthing and Google searches, I was quickly able to identify what had allowed the attack: a misconfigured nginx server can allow non-PHP files to be executed as PHP. As I researched the vulnerability a bit more, however, I realized that many of the nginx / PHP setup tutorials found on the Internet suggest that people use vulnerable configurations.
The misconfiguration

As I mentioned, the attack was made possible by a very simple misconfiguration between nginx and php-fastcgi. Consider the configuration block below, taken from a tutorial at http://library.linode.com/web-servers/nginx/php-fastcgi/fedora-14:

server {
   listen 80;
   server_name www.bambookites.com bambookites.com;
   access_log /srv/www/www.bambookites.com/logs/access.log;
   error_log /srv/www/www.bambookites.com/logs/error.log;
   root /srv/www/www.bambookites.com/public_html;
 
   location / {
       index  index.html index.htm index.php;
   }
 
   location ~ \.php$ {
       include /etc/nginx/fastcgi_params;
       fastcgi_pass  127.0.0.1:9000;
       fastcgi_index index.php;
       fastcgi_param  SCRIPT_FILENAME /srv/www/www.bambookites.com/public_html$fastcgi_script_name;
   }
}

It may not be immediately clear, but this configuration block allows for arbitrary code execution under certain circumstances (and I don’t just mean if an attacker can upload a file ending in .php: that kind of vulnerability is independent of the web server used).

Consider a situation where remote users can upload their own pictures to the site. Lets say that an attacker uploads an image to http://www.bambookites.com/uploads/random.gif. What happens, given the server block above, if the attacker then browses to http://www.bambookites.com/uploads/random.gif/somefilename.php?

1. nginx will look at the URL, see that it ends in .php, and pass the path along to the PHP fastcgi handler.
2. PHP will look at the path, find the .gif file in the filesystem, and store /somefilename.php in $_SERVER['PATH_INFO'], executing the contents of the GIF as PHP.

Since GIFs and other image types can contain arbitrary content within them, it’s possible to craft a malicious image that contains valid PHP. That is how the attacker was able to compromise the server: he or she uploaded a malicious image containing PHP code to the site, then browsed to the file in a way that caused it to be parsed as PHP.

This issue was first discovered almost a year ago. The original report can be found in Chinese at http://www.80sec.com/nginx-securit.html. There is also a discussion about it on the nginx forums.

This issue can be mitigated in a number of ways, but there are downsides associated with each of the possibilities:

1. Set cgi.fix_pathinfo to false in php.ini (it’s set to true by default). This change appears to break any software that relies on PATH_INFO being set properly (eg: WordPress).
2. Add try_files $uri =404; to the location block in your nginx config. This only works when nginx and the php-fcgi workers are on the same physical server.
3. Add a new location block that tries to detect malicious URLs. Unfortunately, detecting based on the URL alone is impossible: files don’t necessarily need to have extensions (eg: README, INSTALL, etc).
4. Explicitly exclude upload directories using an if statement in your location block. The disadvantage here is the use of a blacklist: you have to keep updating your nginx configuration every time you install a new application that allows uploads.
5. Don’t store uploads on the same server as your PHP. The content is static anyway: serve it up from a separate (sub)domain. Of course, this is easier said than done: not all web applications make this easy to do.

[Note: If anyone is aware of other possible solutions (or workarounds to improve the effectiveness of these solutions), please let me know and I'll add them here!]
Tutorials

Now, the configuration file for the compromised server wasn’t written by hand. When the server was set up, the configuration was created based on suggestions found on the Internet. I assume that other people use tutorials and walkthroughs for setting up their servers as well. Unfortunately, most of the documentation for configuring nginx and php-fastcgi still encourages people to set up their servers in a vulnerable way.

1. The default configuration file for nginx suggests the use of an insecure location block (source).
2. The nginx wiki supplies potentially dangerous examples as well. To be fair, some pages do encourage users to explicitly prevent PHP execution in upload directories [Edit: and in the Pitfalls document, which everyone should read before configuring nginx]. However, other pages ignore the issue entirely.
3. The Linode Library has an extensive collection of documents, including a number that talk about setting up nginx and PHP on various OSes. Unfortunately, all of those tutorials suggest using a vulnerable configuration for PHP. I’ve contacted the documentation team at Linode and I’m waiting to hear back from them.
4. Howto Forge has several tutorials (1, 2) which show up when searching Google for “nginx php setup.” These tutorials also suggest the use of a vulnerable configuration.
5. People have written many tutorials on blogs and other sites (ie: 1, 2). A number of these tutorials encourage using the same vulnerable configuration.

In contrast, codex.wordpress.org provides an excellent configuration example that warns people about and mitigates the vulnerability. I’ve reproduced the relevant portion below:

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
   # Zero-day exploit defense.
   # http://forum.nginx.org/read.php?2,88845,page=3
   # Won't work properly (404 error) if the file is not stored on this
server, which is entirely possible with php-fpm/php-fcgi.
   # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on
another machine.  And then cross your fingers that you won't get hacked.
   try_files $uri =404;
 
   fastcgi_split_path_info ^(.+\.php)(/.+)$;
   include fastcgi_params;
   fastcgi_index index.php;
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#    fastcgi_intercept_errors on;
   fastcgi_pass php;
}

Conclusion

1.If you run PHP on an nginx web server, check your configuration and update if necessary.
2.If you’re doing a security audit on a PHP application running on an nginx web server, remember to test for this configuration.
3. If you run across a tutorial that is out of date, please point the author to this post.
4.If you know of a way to better secure nginx / php-fastcgi, let me know!

================================================================================
Passing Every ~ \.php$ request to to PHP

It is common with Nginx to pass every URI ending in .php to the PHP parser, if using a default PHP build this might lead to security issues. Nginx is a reverse proxy and as such does not have a concept of file unless you specifically tell it to. So if your configuration looks like this.

location ~* \.php$ {
fastcgi_pass backend;
}

Then you are probably vulnerable. The issue is that PHP when configured incorrectly tries to guess which file you want to execute if the full path does not lead to a file. Say you have the URI /forum/avatar/1232.jpg/index.php. The File does not exist but /forum/avatar/1232.jpg does, Nginx does not care and gladly passes the request to PHP as you have instructed it to, PHP sees the file does not exist and that /forum/avatar/1232.jpg does and chooses to execute this. If this file is a user upload it might contain embedded PHP code and you are now vulnerable to arbitrary code execution.

The solution is to set cgi.fix_pathinfo=0 in the php.ini file, this causes PHP to try the literal path given and will thus not execute the jpg file. If for backwards compatibility reasons you cannot change this setting you need to ensure that Nginx is passing PHP an actual file or specifically disable PHP access to any directory containing user uploads.

REFERENCES
https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/

http://wiki.nginx.org/Pitfalls#Passing_Every_.7E_.5C.php.24_request_to_to_PHP

Wednesday, April 6, 2011

Linux Determine which Services are Enabled at Boot

SkyHi @ Wednesday, April 06, 2011
The best protection against vulnerable software is running less software. How do I find out which services are enabled at Boot under CentOS / RHEL / Fedora Linux? How do I disable software which is not needed?

Open terminal and login as root user.
Type the following command to list all services which are enabled at boot:


#chkconfig --list | grep $(runlevel  | awk '{ print $2}'):on


Sample output:


acpid           0:off 1:off 2:off 3:on 4:on 5:on 6:off
anacron         0:off 1:off 2:on 3:on 4:on 5:on 6:off
atd             0:off 1:off 2:off 3:on 4:on 5:on 6:off
auditd          0:off 1:off 2:on 3:on 4:on 5:on 6:off
cpuspeed        0:off 1:on 2:on 3:on 4:on 5:on 6:off
crond           0:off 1:off 2:on 3:on 4:on 5:on 6:off
dkms_autoinstaller 0:off 1:off 2:on 3:on 4:on 5:on 6:off
haldaemon       0:off 1:off 2:off 3:on 4:on 5:on 6:off
hidd            0:off 1:off 2:on 3:on 4:on 5:on 6:off
irqbalance      0:off 1:off 2:on 3:on 4:on 5:on 6:off
kudzu           0:off 1:off 2:off 3:on 4:on 5:on 6:off
lighttpd        0:off 1:off 2:on 3:on 4:on 5:on 6:off
lm_sensors      0:off 1:off 2:on 3:on 4:on 5:on 6:off
lvm2-monitor    0:off 1:on 2:on 3:on 4:on 5:on 6:off
mcstrans        0:off 1:off 2:on 3:on 4:on 5:on 6:off
mdmonitor       0:off 1:off 2:on 3:on 4:on 5:on 6:off
messagebus      0:off 1:off 2:off 3:on 4:on 5:on 6:off
microcode_ctl   0:off 1:off 2:on 3:on 4:on 5:on 6:off
mysqld          0:off 1:off 2:on 3:on 4:on 5:on 6:off
named           0:off 1:off 2:on 3:on 4:on 5:on 6:off
netfs           0:off 1:off 2:off 3:on 4:on 5:on 6:off
network         0:off 1:off 2:on 3:on 4:on 5:on 6:off
ntpd            0:off 1:off 2:on 3:on 4:on 5:on 6:off
pcscd           0:off 1:off 2:on 3:on 4:on 5:on 6:off
psacct          0:off 1:off 2:on 3:on 4:on 5:on 6:off
readahead_early 0:off 1:off 2:on 3:on 4:on 5:on 6:off
restorecond     0:off 1:off 2:on 3:on 4:on 5:on 6:off
rhnsd           0:off 1:off 2:on 3:on 4:on 5:on 6:off
rpcgssd         0:off 1:off 2:off 3:on 4:on 5:on 6:off
rpcidmapd       0:off 1:off 2:off 3:on 4:on 5:on 6:off
sendmail        0:off 1:off 2:on 3:on 4:on 5:on 6:off
setroubleshoot  0:off 1:off 2:off 3:on 4:on 5:on 6:off
smartd          0:off 1:off 2:on 3:on 4:on 5:on 6:off
snmpd           0:off 1:off 2:on 3:on 4:on 5:on 6:off
sshd            0:off 1:off 2:on 3:on 4:on 5:on 6:off
stor_agent      0:off 1:off 2:off 3:on 4:off 5:on 6:off
syslog          0:off 1:off 2:on 3:on 4:on 5:on 6:off
sysstat         0:off 1:off 2:on 3:on 4:off 5:on 6:off
vmware          0:off 1:off 2:on 3:on 4:off 5:on 6:off
xfs             0:off 1:off 2:on 3:on 4:on 5:on 6:off
xinetd          0:off 1:off 2:off 3:on 4:on 5:on 6:off
yum-updatesd    0:off 1:off 2:on 3:on 4:on 5:on 6:off



The first column of above output is the name of a service which is currently enabled at boot. You need to review each service.

Task: Disable service

To stop service, enter:
# service {service-name} stop
# service vmware stop

To disable service, enter:
# chkconfig {service-name} off
# chkconfig vmware off

You can also use ntsysv command to manage all services.

A note about outdated insecure service

All of the following services must be disabled to improve server security:
  1. Inetd and Xinetd (inetd xinetd) - Use direct services configured via SysV and daemons.
  2. Telnet (telnet-server) - Use ssh
  3. Rlogin, Rsh, and Rcp ( rsh-server ) - Use ssh and scp.
  4. NIS (ypserv) : Use OpenLDAP or Fedora directory server.
  5. TFTP (tftp-server) : Use SFTP or SSH.
To delete all of the service enter:
# yum erase inetd xinetd ypserv tftp-server telnet-server rsh-serve

A note about Debian / Ubuntu Linux

Please see my comment below, to find out which services are enabled at boot under Debian / Ubuntu Linux and disable software which is not needed.

To list all boot time enabled services use the following costume shell code (type at command prompt):


R=$(runlevel  | awk '{ print $2}')
for s in /etc/rc${R}.d/*; do  basename $s | grep '^S' | sed 's/S[0-9].//g' ;done



Sample output:

policykit
vbesave
acpid
powernowd.early
sysklogd
xserver-xorg-input-wacom
klogd
dbus
avahi-daemon
dnsmasq
mysql-ndb-mgm
mysql-ndb
mysql
acct
apmd
apport
argus-server
dkms_autoinstaller
fancontrol
festival
hddtemp
ipmievd
nscd
scanlogd
sysstat
tcpspy
varnish
vboxdrv
vsftpd
winbind
aumix
dhcdbd
hal
pulseaudio
gdm
squid
system-tools-backends
radvd
anacron
atd
cron
binfmt-support
tomcat5.5
apache2
usplash
acpi-support
laptop-mode
rc.local
rmnologin
stop-readahead


 To turn off service use T-GUI tools like rcconf or simply type:

update-rc.d -f {service-name} remove

 update-rc.d {service-name} stop 20 2 3 4 5 .


For example, remove apache2, enter:


update-rc.d -f apache2 remove
update-rc.d apache2 stop 20 2 3 4 5 .


Use rcconf tool to view enabled services. See the following posts for more info about Debian / Ubuntu services:
REFERENCES
http://www.cyberciti.biz/faq/linux-determine-which-services-are-enabled-at-boot/#comment-41093

Monday, April 4, 2011

crontab relative path question problem

SkyHi @ Monday, April 04, 2011
You've got a relative path in there (localhost/cron.php) - always use the absolute path. When the cron job tries to run, its base directory may not be where you think it is. If it's your own cron (not root's), and you don't have write access to where it's starting, that could cause the issue.

crontab does not preserve your environment and so when your process is started it gets a fresh, clean and empty shell to work in.
"at" and "batch" on the other hand (from memory), do indeed preserve your shell environment.

Friday, April 1, 2011

Ubuntu use Python 2 and Python 3 together

SkyHi @ Friday, April 01, 2011
sudo apt-get install python
sudo apt-get install python3



Ubuntu deliberately packages python3 in such a way it won't interfere with python2.

To run your programs, you'll type "python3" at the command line instead of just "python".

How To Save Traffic With Apache2's mod_deflate

SkyHi @ Friday, April 01, 2011
In this tutorial I will describe how to install and configure mod_deflate on an Apache2 web server. mod_deflate allows Apache2 to compress files and deliver them to clients (e.g. browsers) that can handle compressed content which most modern browsers do. With mod_deflate, you can compress HTML, text or XML files to approx. 20 - 30% of their original sizes, thus saving you server traffic and making your modem users happier.
Compressing files causes a slightly higher load on the server, but in my experience this is compensated by the fact that the clients' connection times to your server decrease a lot. For example, a modem user that needed seven seconds to download an uncompressed HTML file might now only need two seconds for the same, but compressed file.
By using mod_deflate you don't have to be afraid that you exclude users with older browsers that cannot handle compressed content. The browser negotiates with the server before any file is transferred, and if the browser does not have the capability to handle compressed content, the server delivers the files uncompressed.
mod_deflate has replaced Apache 1.3's mod_gzip in Apache2. If you want to serve compressed files with Apache 1.3, take a look at this tutorial: mod_gzip - serving compressed content by the Apache webserver
I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!

1 Enable mod_deflate

If you have Apache2 installed, mod_deflate should also already be installed on your system. Now we have to enable it. On Debian, we can do it like this:
a2enmod deflate
Then restart Apache2:
/etc/init.d/apache2 restart
On other distributions you might have to edit Apache2's configuration manually to enable mod_deflate. You might have to add a line like this to the LoadModule section:

LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so



Make sure you adjust the path to mod_deflate.so, and restart Apache2 afterwards.

2 Configure mod_deflate

The compression of files can be configured in one of two ways: either explicit exclusion of files by extension or explicit inclusion of files by MIME type. You can enable mod_deflate for your whole Apache2 server, or just for specific virtual sites. Depending on this, either open your Apache2's global server configuration section now or just the vhost configuration section where you want to enable mod_deflate.

2.1 Explicit Inclusion Of Files By MIME Type

If you want to compress HTML, text, and XML files only, add this line to your configuration:

AddOutputFilterByType DEFLATE text/html text/plain text/xml


This is the configuration I'm using because I don't want to compress images or PDF files or already compressed files such as zip files.

2.2 Explicit Exclusion Of Files By Extension

If you want to compress all file types and exclude just a few, you would add something like this to your configuration (instead of the line from section 2.1):

SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ \
    no-gzip dont-vary
SetEnvIfNoCase Request_URI \
    \.(?:exe|t?gz|zip|bz2|sit|rar)$ \
    no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary






This would compress all files except images (gif, jpg, and png), already compressed files (like zip and tar.gz) and PDF files which makes sense because you do not gain much by compressing these file types.

2.3 Further Configuration Directives

Regardless whether you use the configuration from section 2.1 or 2.2, you should add these lines to your configuration:


BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html




These lines are for some older browsers that do not support compression of files other than HTML documents.
The configuration is now finished, and you must now restart Apache2. On Debian, you do it like this:
/etc/init.d/apache2 restart
To learn about further configuration directives, take a look at Apache Module mod_deflate.

3 Testing

To test our compression, we add a few directives to our mod_deflate configuration that log the compression ratio of delivered files. Open your mod_deflate configuration and add the following lines:


DeflateFilterNote Input input_info
DeflateFilterNote Output output_info
DeflateFilterNote Ratio ratio_info
LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
CustomLog /var/log/apache2/deflate_log deflate



Make sure you replace /var/log/apache2 with your Apache2's log directory. This could be /var/log/httpd, /var/log/httpd2, etc.
Then restart Apache2. On Debian, do it like this:
/etc/init.d/apache2 restart
Now whenever a file is requested this will be logged in /var/log/apache2/deflate_log (or to whatever file you changed it to). A typical log line looks like this:

"GET /info.php HTTP/1.1" 7621/45430 (16%)



You see that the file info.php was requested and delivered. Its original size was 45430 bytes, and it was compressed to 7621 bytes or 16% of its original size! This is a great result, and if your web site mostly consists out of HTML, text, and XML files, mod_deflate will save you a lot of traffic, and for users with a low-bandwidth connection your site will load much faster.
If you don't need the logging after your tests anymore, you can undo the changes from section 3 and restart Apache2.

4 Links


REFERENCES
http://www.howtoforge.com/apache2_mod_deflate