Wednesday, October 28, 2009

Kernel Parameter: Setting the Kernel Parametre?

How do I set advanced security options of the TCP/IP stack and virtual memory to improve security and performance of my system? How do I configure Linux kernel to prevent certain kinds of attacks using /etc/sysctl.conf? How do I set Linux kernel parameters?

sysctl is an interface that allows you to make changes to a running Linux kernel. With /etc/sysctl.conf you can configure various Linux networking and system settings such as:

1. Limit network-transmitted configuration for IPv4
2. Limit network-transmitted configuration for IPv6
3. Turn on execshild protection
4. Prevent against the common 'syn flood attack'
5. Turn on source IP address verification
6. Prevents a cracker from using a spoofing attack against the IP address of the server.
7. Logs several types of suspicious packets, such as spoofed packets, source-routed packets, and redirects.

sysctl command

The sysctl command is used to modify kernel parameters at runtime. /etc/sysctl.conf is a text file containing sysctl values to be read in and set by sysct at boot time. To view current values, enter:
# sysctl -a
# sysctl -A
# sysctl mib
# sysctl net.ipv4.conf.all.rp_filter
To load settings, enter:
# sysctl -p
Sample /etc/sysctl.conf

Edit /etc/sysctl.conf and update it as follows. The file is documented with comments. However, I recommend reading the official Linux kernel sysctl tuning help file (see below):

# The following is suitable for dedicated web server, mail, ftp server etc.
# ---------------------------------------
# BOOLEAN Values:
# a) 0 (zero) - disabled / no / false
# b) Non zero - enabled / yes / true
# --------------------------------------
# Controls IP packet forwarding
net.ipv4.ip_forward = 0

# Controls source route verification
net.ipv4.conf.default.rp_filter = 1

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0

# Controls whether core dumps will append the PID to the core filename
# Useful for debugging multi-threaded applications
kernel.core_uses_pid = 1

# Controls the use of TCP syncookies
#net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 2

########## IPv4 networking start ##############
# Send redirects, if router, but this is just server
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Accept packets with SRR option? No
net.ipv4.conf.all.accept_source_route = 0

# Accept Redirects? No, this is not router
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0

# Log packets with impossible addresses to kernel log? yes
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0

# Ignore all ICMP ECHO and TIMESTAMP requests sent to it via broadcast/multicast
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Prevent against the common 'syn flood attack'
net.ipv4.tcp_syncookies = 1

# Enable source validation by reversed path, as specified in RFC1812
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

########## IPv6 networking start ##############
# Number of Router Solicitations to send until assuming no routers are present.
# This is host and not router
net.ipv6.conf.default.router_solicitations = 0

# Accept Router Preference in RA?
net.ipv6.conf.default.accept_ra_rtr_pref = 0

# Learn Prefix Information in Router Advertisement
net.ipv6.conf.default.accept_ra_pinfo = 0

# Setting controls whether the system will accept Hop Limit settings from a router advertisement
net.ipv6.conf.default.accept_ra_defrtr = 0

#router advertisements can cause the system to assign a global unicast address to an interface
net.ipv6.conf.default.autoconf = 0

#how many neighbor solicitations to send out per address?
net.ipv6.conf.default.dad_transmits = 0

# How many global unicast IPv6 addresses can be assigned to each interface?
net.ipv6.conf.default.max_addresses = 1

########## IPv6 networking ends ##############

#Enable ExecShield protection
kernel.exec-shield = 1
kernel.randomize_va_space = 1

# TCP and memory optimization
# increase TCP max buffer size setable using setsockopt()
#net.ipv4.tcp_rmem = 4096 87380 8388608
#net.ipv4.tcp_wmem = 4096 87380 8388608

# increase Linux auto tuning TCP buffer limits
#net.core.rmem_max = 8388608
#net.core.wmem_max = 8388608
#net.core.netdev_max_backlog = 5000
#net.ipv4.tcp_window_scaling = 1

# increase system file descriptor limit
fs.file-max = 65535

#Allow for more PIDs
kernel.pid_max = 65536

#Increase system IP port limits
net.ipv4.ip_local_port_range = 2000 65000

Sunday, October 25, 2009

Apache:Piped logging program to rotate Apache logs

There was a requirement from IT Infrastructure Team that the Apache Logs has always been cumbersome to maintain as it gets full due to heavy rush at the server end. They needed a utility to rotate the logs as per their requirement.

I explored tools for apache logs maintenance and finally got a chance to try out something.Here is my finding:

rotatelogs is a simple program for use in conjunction with Apache's piped logfile feature. For example:

CustomLog "|rotatelogs /var/logs/logfile 86400" common

This creates the files /var/logs/logfile.nnnn where nnnn is the system time at which the log nominally starts (this time will always be a multiple of the rotation time, so you can synchronize cron scripts with it). At the end of each rotation time (here after 24 hours) a new log is started.

CustomLog "|rotatelogs /var/logs/logfile 5M" common

This configuration will rotate the logfile whenever it reaches a size of 5 megabytes.

ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M"

This configuration will rotate the error logfile whenever it reaches a size of 5 megabytes, and the suffix to the logfile name will be created of the form errorlog.YYYY-mm-dd-HH_MM_SS.

■ Synopsis
■ Options
■ Portability
rotatelogs [ -l ] logfile [ rotationtime [ offset ]] | [ filesizeM ]

-l (2.0.51 and later)
Causes the use of local time rather than GMT as the base for the interval. Note that using -l in an environment which changes the GMT offset (such as for BST or DST) can lead to unpredictable results!
The path plus basename of the logfile. If logfile includes any '%' characters, it is treated as a format string for strftime(3). Otherwise, the suffix .nnnnnnnnnn is automatically added and is the time in seconds. Both formats compute the start time from the beginning of the current period.
The time between log file rotations in seconds.
The number of minutes offset from UTC. If omitted, zero is assumed and UTC is used. For example, to use local time in the zone UTC -5 hours, specify a value of -300 for this argument.
The maximum file size in megabytes followed by the letter M to specify size rather than time. Use this parameter in place of both rotationtime and offset.
The following logfile format string substitutions should be supported by all strftime(3) implementations, see the strftime(3) man page for library-specific extensions.

%A full weekday name (localized)
%a 3-character weekday name (localized)
%B full month name (localized)
%b 3-character month name (localized)
%c date and time (localized)
%d 2-digit day of month
%H 2-digit hour (24 hour clock)
%I 2-digit hour (12 hour clock)
%j 3-digit day of year
%M 2-digit minute
%m 2-digit month
%p am/pm of 12 hour clock (localized)
%S 2-digit second
%U 2-digit week of year (Sunday first day of week)
%W 2-digit week of year (Monday first day of week)
%w 1-digit weekday (Sunday first day of week)
%X time (localized)
%x date (localized)
%Y 4-digit year
%y 2-digit year
%Z time zone name
%% literal `%'

Note: Do create the logs directory under /var directory.
For testing, Just restart the httpd service and you will see these directories:

[root@localhost logs]# ls -la
total 28
drwxr-xr-x 2 root root 4096 2009-10-26 01:45 .
drwxr-xr-x. 23 root root 4096 2009-10-26 01:13 ..
-rw-r--r-- 1 root root 632 2009-10-26 01:43 errorlog.2009-10-25-20_13_59
-rw-r--r-- 1 root root 632 2009-10-26 01:44 errorlog.2009-10-25-20_14_15
-rw-r--r-- 1 root root 0 2009-10-26 01:13 logfile
-rw-r--r-- 1 root root 310 2009-10-26 01:21 logfile.1256500257
-rw-r--r-- 1 root root 381 2009-10-26 01:39 logfile.1256501364
-rw-r--r-- 1 root root 81 2009-10-26 01:44 logfile.1256501673
[root@localhost logs]#

Friday, October 23, 2009

Apache:SSH Public key based authentication – Howto

This howto covers generating and using ssh keys for automated:

a) Login

b) Make backups

c) Run commands from shell etc
Task: Generating ssh keys

1) Log on to your workstation ( for example log on to workstation called as vivek user). Please refer the following sample setup - You will be log in, on your local system, AS THE USER you wish to make passwordless ssh connections.

My Setup
(Click image to enlarge)

2) Create the Cryptographic Key on FreeBSD workstation, enter:

$ ssh-keygen -t rsa

Assign the pass phrase (press [enter] key twice if you don't want a passphrase). It will create 2 files in ~/.ssh directory as follows:

* ~/.ssh/id_rsa : identification (private) key
* ~/.ssh/ : public key

3) Use scp to copy the (public key) to server as authorized_keys2 file, this is know as Installing the public key to server.

$ scp .ssh/

4) From FreeBSD workstation login to server:

$ ssh

5) Changing the pass-phrase on workstation (if needed):

$ ssh-keygen -p

6) Use of ssh-agent to avoid continues pass-phrase typing
At freebsd workstation type:

$ ssh-agent $BASH
$ ssh-add

Type your pass-phrase

From here, whenever connecting to server it won’t ask for password.
Above two commands can be added to ~/.bash_profile so that as soon as I login into workstation I can set the agent.

7) Deleting the keys hold by ssh-agent

a) To delete all keys

$ ssh-add -D

b) To delete specific key

$ ssh-add -d key

c) To list keys

$ ssh-add -l

Apache:Howto Linux / UNIX setup SSH with DSA public key authentication (password less login)

I have Linux laptop called tom and remote Linux server called jerry. How do I setup DSA based authentication so I don’t have to type password?


DSA public key authentication can only be established on a per system / user basis only i.e. it is not system wide. You will be setting up ssh with DSA public key authentication for SSH version 2 on two machines:

#1 machine : your laptop called tom
#2 machine : your remote server called jerry
Command to type on your laptop/desktop (local computer)

First login to local computer called tom and type the following command.
Step #1: Generate DSA Key Pair

Use ssh-keygen command as follows:
$ ssh-keygen -t dsa

Enter file in which to save the key (/home/vivek/.ssh/id_dsa): Press [Enter] key
Enter passphrase (empty for no passphrase): myPassword
Enter same passphrase again: myPassword
Your identification has been saved in /home/vivek/.ssh/id_dsa.
Your public key has been saved in /home/vivek/.ssh/
The key fingerprint is:
04:be:15:ca:1d:0a:1e:e2:a7:e5:de:98:4f:b1:a6:01 vivek@vivek-desktop

Caution: a) Please enter a passphrase different from your account password and confirm the same.
b) The public key is written to /home/you/.ssh/
c) The private key is written to /home/you/.ssh/id_dsa.
d) It is important you never-ever give out your private key.
Step #2: Set directory permission

Next make sure you have correct permission on .ssh directory:
$ cd
$ chmod 755 .ssh
Step #3: Copy public key

Now copy file ~/.ssh/ on Machine #1 (tom) to remote server jerry as ~/.ssh/authorized_keys:
$ scp ~/.ssh/ user@jerry:.ssh/authorized_keys
Command to type on your remote server called jerry

Login to your remote server and make sure permissions are set correct:
$ chmod 600 ~/.ssh/authorized_keys
Task: How do I login from client to server with DSA key?

Use scp or ssh as follows from your local computer:
$ ssh user@jerry
$ ssh
$ scp file user@jerry:/tmp

You will still be asked for the passphrase for the DSA key file each time you connect to remote server called jerry, unless you either did not enter a passphrase when generating the DSA key pair.
Task: How do I login from client to server with DSA key but without typing a passhrase i.e. password-less login?

Type the following command at shell prompt:
$ exec /usr/bin/ssh-agent $SHELL
$ ssh-add

Enter passphrase for /home/vivek/.ssh/id_dsa: myPassword
Identity added: /home/vivek/.ssh/id_dsa (/home/vivek/.ssh/id_dsa)

Type your passhrase once. Now, you should not be prompted for a password whenever you use ssh, scp, or sftp command.

If you are using GUI such as Gnome use the command:
$ ssh-askpass
$ /usr/lib/openssh/gnome-ssh-askpass

To save your passphrase during your GNOME session under Debian / Ubuntu, do as follows:
a) Click on System
b) Select Preferences
c) Select Session
d) Click on New
e) Enter "OpenSSH Password Management" in the Name text area
f) Enter /usr/lib/openssh/gnome-ssh-askpass in the command text area.
Howto Linux / UNIX setup SSH with DSA public key authentication
g) Click on close to save the changes
h) Log out and then log back into GNOME. After GNOME is started, a dialog box will appear prompting you for your passphrase. Enter the passphrase requested. From this point on, you should not be prompted for a password by ssh, scp, or sftp.

Apache:How To Back Up a Web Server ?

I'm busy experimenting with Red Hat Enterprise Linux based Apache web server. I want to backup my Apache webserver, MySQL and PostgreSQL database to another disk called /backup and then copy it to other offsite backup ssh server called
I started this morning with a piece of refreshment in Breakfast and soon caught hold of one of my friend online.He was Domino from Netherland and we met through one of linux forum. He wanted me to help him with the same and I started writing.

Here we go...

There are many tools under Linux / UNIX to backup a webserver. You can create a simple shell script to backup everything to /backup directory. You can also copy /backup directory content offsite using ssh and scp tool.

Step # 1: Create /root/ script

Use the following shell script:

# A Simple Shell Script to Backup Red Hat / CentOS / Fedora / Debian / Ubuntu Apache Webserver and SQL Database
# Path to backup directories
DIRS="/home/vivek/ /var/www/html/ /etc"

# Store todays date
NOW=$(date +"%F")

# Store backup path

# Backup file name hostname.time.tar.gz
BFILE="$(hostname).$(date +'%T').tar.gz"
PFILE="$(hostname).$(date +'%T').pg.sql.gz"
MFILE="$(hostname).$(date +'%T').mysql.sq.gz"

# Set Pgsql username

# Set MySQL username and password

# Remote SSH server setup
SSHSERVER="" # your remote ssh server
SSHUSER="ajeet" # username
SSHDUMPDIR="/backup/remote" # remote ssh server directory to store dumps

# Paths for binary files

# make sure backup directory exists
[ ! -d $BACKUP ] && mkdir -p ${BACKUP}

# Log backup start time in /var/log/messages
$LOGGER "$0: *** Backup started @ $(date) ***"

# Backup websever dirs
$TAR -zcvf ${BACKUP}/${BFILE} "${DIRS}"

# Backup PgSQL

# Backup MySQL
$MYSQLDUMP -u ${MYSQLUSER} -h localhost -p${MYSQLPASSWORD} --all-databases | $GZIP -9 > ${BACKUP}/${MFILE}

# Dump all local files to failsafe remote UNIX ssh server / home server

# Log backup end time in /var/log/messages
$LOGGER "$0: *** Backup Ended @ $(date) ***"

Customize it according to your needs, set username, password, ssh settings and other stuff.

Step # 2: Create ssh keys

Create ssh keys for password less login from your server to another offsite server hosted at your own home or another datacenter. See following faqs for more information:
Step #3: Create Cron job

Setup a cronjob to backup server everyday, enter:
# crontab -e
Append following code to backup server everyday at midnight:
@midnight /root/

Apache: Giving Users their Own URL

Exploring more on Apache and continuing with my Cookbook, I started with this topic and set it up in just 5 minutes. This time I tried setting up webpage for all users and this is what I finally got it working !!!

File: /etc/httpd/conf/httpd.conf

Line 352:
UserDir public_html

And remove the hash sign:

368 AllowOverride FileInfo AuthConfig Limit
369 Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
371 Order allow,deny
372 Allow from all

375 Order deny,allow
376 Deny from all



Restart the Apache Service.

Try Browsing : http://localhost/~ajeet
But it wont work.

Reason: Permission Issue

Create few users like ajeet, john, eric etc

#useradd ajeet
#passwd ajeet
#cd /hom/ajeet
#mkdir public_html
#cd public_html
#mkdir {ISO1,ISO2,ISO3)

Grant Permission:

#chmod o+x /home /home/ajeet
#chmod o+x /home/ajeet/public_html

Try Browsing http://localhost/~ajeet

Index of /~ajeet
[ICO] Name Last modified Size Description
[DIR] Parent Directory -
[DIR] ISO/ 23-Oct-2009 23:11 -
[DIR] ISO2/ 23-Oct-2009 23:11 -
[DIR] ISO3/ 23-Oct-2009 23:11 -
Apache/2.2.11 (Fedora) Server at localhost Port 80

So User can have their own Webpage.
Happy Apaching !!!

Apache: Authenticating Directory Structure

This morning I started with authenticating the portion of my Directory Structure.
This is what I did:

File: /etc/httpd/conf/httpd.conf

Directory /
Options FollowSymLinks
AllowOverride All

Directory "/var/www/html"
Options Indexes FollowSymLinks
AllowOverride AuthConfig
Order allow,deny
Allow from all


Thats what we really need to be done with httpd.conf

Lets Create a New Directory Structure:

#cd /var/www/html
#mkdir pdfs
#cd pdfs
#mkdir (RHEL4,RHEL4.2,RHEL5,RHEL5.2}
#cd RHEL5
#cd ISO
[root@localhost RHEL5]# ls -la
total 24
drwxr-xr-x. 6 apache apache 4096 2009-10-23 19:02 .
drwxr-xr-x. 6 apache apache 4096 2009-10-19 09:41 ..
drwxr-xr-x 5 apache apache 4096 2009-10-23 19:35 ISO
drwxr-xr-x 2 apache apache 4096 2009-10-23 18:08 RPMS
drwxr-xr-x 2 apache apache 4096 2009-10-23 18:08 SOURCES
drwxr-xr-x 2 apache apache 4096 2009-10-23 18:08 SRC
[root@localhost RHEL5]#
[root@localhost ISO]# ls -la
total 24
drwxr-xr-x 5 apache apache 4096 2009-10-23 19:35 .
drwxr-xr-x. 6 apache apache 4096 2009-10-23 19:02 ..
-rw-r--r-- 1 root root 106 2009-10-23 19:35 .htaccess
drwxr-xr-x 2 apache apache 4096 2009-10-23 19:02 ISO1
drwxr-xr-x 2 apache apache 4096 2009-10-23 19:02 ISO2
drwxr-xr-x 2 apache apache 4096 2009-10-23 19:02 ISO3
[root@localhost ISO]#
[root@localhost ISO]# ls -la
total 24
drwxr-xr-x 5 apache apache 4096 2009-10-23 19:35 .
drwxr-xr-x. 6 apache apache 4096 2009-10-23 19:02 ..
-rw-r--r-- 1 apache apache 106 2009-10-23 19:35 .htaccess
drwxr-xr-x 2 apache apache 4096 2009-10-23 19:02 ISO1
drwxr-xr-x 2 apache apache 4096 2009-10-23 19:02 ISO2
drwxr-xr-x 2 apache apache 4096 2009-10-23 19:02 ISO3
[root@localhost ISO]#

Under .htaccess file entry includes:

[root@localhost ISO]# cat .htaccess
AuthType Basic
AuthName "Authentication Required"
AuthUserFile /var/www/html/htpasswd
Require user jan

[root@localhost ISO]#

Now Create htpasswd file under /var/www/html directory as:

htpasswd -bcm /var/www/html/htpasswd jan jan123

Now Try Browsing :


Thursday, October 22, 2009

Apache: Deny access to certain file types

How to deny access to certain file types.

Useful: to deny access to certain files that contain private information (log files, source code, password files, etc.).

I a previous tip (Hide a file type from directory indexes) I have showed how we can hide some files from appearing in directory indexes. Even if the files will not appear in directory indexes this will not imply that access to the files will be denied and if a remote user knows the exact location of the file, he will still be able to access the file from a browser… How can someone find out about the location of the private file? well this doesn’t really matter too much, but he might see paths, or files, shown in a warning messages, or the files might be browsable (there is no hiding of the files in the directory indexes).
So if there are ’special files’ that you want to not be served in any case to remote users then you will have to deny access to them.

In order to achieve this we will be using the standard apache module mod_access that will allow us to define rules for various contexts (, , and sections). In this case we will be interested in the section.

Allow/Deny Directive in
Your apache might contain in the default configuration (or at least it would be nice) a configuration similar to the following one that will deny access from the browser to .htaccess files:

Order allow,deny
Deny from all

This is a simple example of how we can deny access to a single file by its name. If you don’t have such a configuration, then it might be a good idea to add it .

Let’s see how we can deny access to several files; let’s consider that we want to deny access to all files with the extension .inc (includes in our php application). In order to achieve this we will add the following configuration lines in the appropriate context (either global config, or vhost/directory, or from .htaccess):

Order allow,deny
Deny from all

Similar to this we can deny access to whatever files we might need

Apache:Deny access to some folders in Apache Directory Indexing

Let’s see how we can deny access to all the .svn folders that exist on the server.In order to achieve this we will add the following configuration lines in the appropriate context (either global config, or vhost/directory, or from .htaccess):

Order allow,deny
Deny from all

Similar to this we can deny access to other folders we might need…

Note: this will show a Forbidden page (code 403) even if the folder does not exist and it is just called from the browser in the url.
Another way how this can be quickly accomplished is by using a Rewrite rule:

RewriteRule ^(.*/)?\\.svn/ - [F,L]or using a redirect:

RedirectMatch 404 /\\.svn(/|$)(in this last example I am using 404 as the returned code so this looks like the folder doesn’t exist on the server; of course if you prefer you can return 403 – forbidden code

Apache: Hide some files from appearing in directory indexes.

To prevent certain files from appearing in directory indexes, in case this needs to remain enabled. This is particularly useful for non html files (or raw files not parsed by apache and returned as a html to the browser), for example: php include files, libraries (that will not have the extension php), or log files, or any other file that you might want to prevent the users to easily see in the browser.

Normally I will disable directory indexes, and this will not be needed, but in case you have to keep directory indexes ON for some reason, then it is a good idea to hide some files from showing in the directory indexes.
This will not prevent peoples to download the files as long as they know (or guess) the file name/location, it will just hide the files from the index generation. Some good examples of what files to hide like this:

•.htaccess (for obvious reasons)
•*.bak *~ (this can lead to download the source of some parsed web files that are saved as backup files)
•RCS CVS *,v *,t (hide cvs related files)
•*.inc (or whatever files extensions you might use to include in regular php files)
These are just examples and you should use this directive based on your particular need.


We will use the apache directive IndexIgnore to hide the list of files. Since this can be used in global configuration and also in virtual host configuration, per directory or in .htaccess it is useful to know that any new IndexIgnore line will actually add the files to the list of hidden files and not overwrite a previous definition. So you can choose this as you see it fit (add them all in one place in a single line, or have more ignore list defined, etc.). To achieve our sample here is how we will hide the file types from above to appear in directory indexes:

IndexIgnore .htaccess
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
IndexIgnore *.incOr the same thing in one single line:

IndexIgnore .htaccess .??* *~ *# HEADER* README* RCS CVS *,v *,t *.incSome Linux distributions will include some defaults for this directive, but in case you have directory indexes ON you should really look into this directive and add the files you don’t want the users to see in a browser in a directory index.

Wednesday, October 21, 2009

Apache: Directory Indexing Security - Part II

Welcome Back !!

Lets Discuss more on Directory Indexing.In the Last tutorial, we explored secure aspects with Restricting user with / access under Linux System. Now, we would explore on Enabling Indexing with DocumentRoot.

Create publish Directory

# mkdir /usr/web
#cd /usr/web
#mkdir -p www/publish
#mkdir {Fedora-9,Fedora10}

Say the Main Configuration setting include:

DocumentRoot "/usr/web/www"

If you want to enable indexes generation on some particular directory or vhost just add the Indexes option:

Directory /usr/web/www/publish
Options Indexes FollowSymLinks
AllowOverride None

and this will enable only in that folder the generation of indexes. In this case, you might want to prevent the listing of some file types as seen in my previous post: “Hide a file type from directory indexes“ which we will explore in next tutorial.

Till then, Happy LinuXing !!!

Apache: Directory Indexing Security - Part I

A Web Administrator do always need efficient weapon for securing his web server.One of the major aspect of Apache Security includes Directory Indexing.Today we will study regarding the major Directory Indexing Security aspects.

You might have noticed this entry at Line 288 of httpd.conf under /etc/httpd/conf directory as:

288 directory /
289 Options FollowSymLinks
290 AllowOverride None
291 /Directory

the default Apache access for Directory / is Allow from All

This entry needs to be understood more clearly if admin needs to secure his web server.

The above entry says " If you want to make sure that files outside of your web directory are not accessible,this is one for you".

Generally with Options we have Indexes as +Indexes and -Indexes. If we dont have any , it means its inaccessible.
The Directive means that / is inaccessible in any way thereby securing the access by external source other than DocumentRoot.

Apache: Secure Your Apache in 20 Ways

20 ways to Secure your Apache Configuration

Here are 20 things you can do to make your apache configuration more secure.

Disclaimer: The thing about security is that there are no guarantees or absolutes. These suggestions should make your server a bit tighter, but don't think your server is necessarily secure after following these suggestions.

Additionally some of these suggestions may decrease performance, or cause problems due to your environment. It is up to you to determine if any of the changes I suggest are not compatible with your requirements. In other words proceed at your own risk.

First, make sure you've installed latest security patches
There is no sense in putting locks on the windows, if your door is wide open. As such, if you're not patched up there isn't really much point in continuing any longer on this list. Go ahead and bookmark this page so you can come back later, and patch your server.

Hide the Apache Version number, and other sensitive information.
By default many Apache installations tell the world what version of Apache you're running, what operating system/version you're running, and even what Apache Modules are installed on the server. Attackers can use this information to their advantage when performing an attack. It also sends the message that you have left most defaults alone.

There are two directives that you need to add, or edit in your httpd.conf file:

ServerSignature Off
ServerTokens Prod

The ServerSignature appears on the bottom of pages generated by apache such as 404 pages, directory listings, etc.

The ServerTokens directive is used to determine what Apache will put in the Server HTTP response header. By setting it to Prod it sets the HTTP response header as follows:

Server: ApacheIf you're super paranoid you could change this to something other than "Apache" by editing the source code, or by using mod_security (see below).

Make sure apache is running under its own user account and group
Several apache installations have it run as the user nobody. So suppose both Apache, and your mail server were running as nobody an attack through Apache may allow the mail server to also be compromised, and vise versa.

User apache
Group apache

Ensure that files outside the web root are not served
We don't want apache to be able to access any files out side of its web root. So assuming all your web sites are placed under one directory (we will call this /web), you would set it up as follows:

Order Deny,Allow
Deny from all
Options None
AllowOverride None

Order Allow,Deny
Allow from all

“Note that because we set Options None and AllowOverride None this will turn off all options and overrides for the server. You now have to add them explicitly for each directory that requires an Option or Override.”
Turn off directory browsing
You can do this with an Options directive inside a Directory tag. Set Options to either None or -Indexes

Options -IndexesTurn off server side includes
This is also done with the Options directive inside a Directory tag. Set Options to either None or -Includes

Options -IncludesTurn off CGI execution
If you're not using CGI turn it off with the Options directive inside a Directory tag. Set Options to either None or -ExecCGI

Options -ExecCGIDon't allow apache to follow symbolic links
This can again can be done using the Options directive inside a Directory tag. Set Options to either None or -FollowSymLinks

Options -FollowSymLinksTurning off multiple Options
If you want to turn off all Options simply use:

Options NoneIf you only want to turn off some separate each option with a space in your Options directive:

Options -ExecCGI -FollowSymLinks -IndexesTurn off support for .htaccess files
This is done in a Directory tag but with the AllowOverride directive. Set it to None.

AllowOverride NoneIf you require Overrides ensure that they cannot be downloaded, and/or change the name to something other than .htaccess. For example we could change it to .httpdoverride, and block all files that start with .ht from being downloaded as follows:

AccessFileName .httpdoverride

Order allow,deny
Deny from all
Satisfy All

Run mod_security
mod_security is a super handy Apache module written by Ivan Ristic, the author of Apache Security from O'Reilly press.

You can do the following with mod_security:

•Simple filtering
•Regular Expression based filtering
•URL Encoding Validation
•Unicode Encoding Validation
•Null byte attack prevention
•Upload memory limits
•Server identity masking
•Built in Chroot support
•And more
Disable any unnecessary modules
Apache typically comes with several modules installed. Go through the apache module documentation and learn what each module you have enabled actually does. Many times you will find that you don't need to have the said module enabled.

Look for lines in your httpd.conf that contain LoadModule. To disable the module you can typically just add a # at the beginning of the line. To search for modules run:

grep LoadModule httpd.confHere are some modules that are typically enabled but often not needed: mod_imap, mod_include, mod_info, mod_userdir, mod_status, mod_cgi, mod_autoindex.

Make sure only root has read access to apache's config and binaries
This can be done assuming your apache installation is located at /usr/local/apache as follows:

chown -R root:root /usr/local/apache
chmod -R o-rwx /usr/local/apache
Lower the Timeout value
By default the Timeout directive is set to 300 seconds. You can decrease help mitigate the potential effects of a denial of service attack.

Timeout 45Limiting large requests
Apache has several directives that allow you to limit the size of a request, this can also be useful for mitigating the effects of a denial of service attack.

A good place to start is the LimitRequestBody directive. This directive is set to unlimited by default. If you are allowing file uploads of no larger than 1MB, you could set this setting to something like:

LimitRequestBody 1048576If you're not allowing file uploads you can set it even smaller.

Some other directives to look at are LimitRequestFields, LimitRequestFieldSize and LimitRequestLine. These directives are set to a reasonable defaults for most servers, but you may want to tweak them to best fit your needs. See the documentation for more info.

Limiting the size of an XML Body
If you're running mod_dav (typically used with subversion) then you may want to limit the max size of an XML request body. The LimitXMLRequestBody directive is only available on Apache 2, and its default value is 1 million bytes (approx 1mb). Many tutorials will have you set this value to 0 which means files of any size may be uploaded, which may be necessary if you're using WebDAV to upload large files, but if you're simply using it for source control, you can probably get away with setting an upper bound, such as 10mb:

LimitXMLRequestBody 10485760Limiting Concurrency
Apache has several configuration settings that can be used to adjust handling of concurrent requests. The MaxClients is the maximum number of child processes that will be created to serve requests. This may be set too high if your server doesn't have enough memory to handle a large number of concurrent requests.

Other directives such as MaxSpareServers, MaxRequestsPerChild, and on Apache2 ThreadsPerChild, ServerLimit, and MaxSpareThreads are important to adjust to match your operating system, and hardware.

Restricting Access by IP
If you have a resource that should only by accessed by a certain network, or IP address you can enforce this in your apache configuration. For instance if you want to restrict access to your intranet to allow only the 176.16 network:

Order Deny,Allow
Deny from all
Allow from

Or by IP:

Order Deny,Allow
Deny from all
Allow from
Adjusting KeepAlive settings
According to the Apache documentation using HTTP Keep Alive's can improve client performance by as much as 50%, so be careful before changing these settings, you will be trading performance for a slight denial of service mitigation.

KeepAlive's are turned on by default and you should leave them on, but you may consider changing the MaxKeepAliveRequests which defaults to 100, and the KeepAliveTimeout which defaults to 15. Analyze your log files to determine the appropriate values.

Run Apache in a Chroot environment
chroot allows you to run a program in its own isolated jail. This prevents a break in on one service from being able to effect anything else on the server.

It can be fairly tricky to set this up using chroot due to library dependencies. I mentioned above that the mod_security module has built in chroot support. It makes the process as simple as adding a mod_security directive to your configuration:

SecChrootDir /chroot/apache

Tuesday, October 20, 2009

Apache: Setting up JBoss on Linux

This blog decribes how to install and setup jboss to start automatically on RedHat Linux

Step1: Install Java and set environment variables

Please follow this link for instructions

Step2: Create a user called jboss

It always advisable to create a user "jboss" that can be used to start/stop jboss and can be assign permissions
#useradd jboss

Step3: Download appropriate package from Jboss and Install it

#tar -xvxf
#mv jboss-5.1.0.GA /usr/local/
#chown -R jboss:jboss /usr/local/jboss-5.1.0.GA

Step4: Set Environment variables for JBOSS

Create a file /etc/profile.d/jboss
# touch /etc/profile.d/jboss
# chmod +x /etc/profile.d/jboss

#vi /etc/profile.d/jboss ( Add the following entries)

#***** Set Env Variables for Jboss


Step5: Logout from shell to get the above path settings updated

Note: [Instead of creating /etc/profile.d/jboss we can always update the variables in /etc/profile]

Step6: Configure Jboss to script start automatically on restart

Starting from JBoss 4.0.1 and above a sample start-up script ( eq: for redhat) is supplied with the package , we just need to modify it.

Copy the script to /etc/init.d and name it as jboss

#cp /usr/local/jboss-5.1.0.GA/bin/ /etc/init.d/jboss

#chmod +x /etc/init.d/jboss

Step7: create links

The links will be used to identify at which run levels JBoss should be started and stopped.
#ln -s /etc/rc.d/init.d/jboss /etc/rc3.d/S84jboss
#ln -s /etc/rc.d/init.d/jboss /etc/rc5.d/S84jboss
#ln -s /etc/rc.d/init.d/jboss /etc/rc4.d/S84jboss

#ln -s /etc/rc.d/init.d/jboss /etc/rc6.d/K15jboss
#ln -s /etc/rc.d/init.d/jboss /etc/rc0.d/K15jboss
#ln -s /etc/rc.d/init.d/jboss /etc/rc1.d/K15jboss
#ln -s /etc/rc.d/init.d/jboss /etc/rc2.d/K15jboss
Linux will execute the equivalent of "service jboss start" for the "S" links and "service jboss stop" for the K links.

Red Hat has a chkconfig command to manage these links, which may or may not work (it uses comments in the top of the script to determine which run-levels it should be started/stopped in)

Step8: Modify the script to work with chkconfig command in Redhat

Add the following entries just after #!/bin/sh in the script

# JBoss Control Script
# chkconfig: 345 80 20
# description: JBoss Startup File
# To use this script run it as root - it will switch to the specified user
Step9: Modify the script with JJboss,JavaPath, User and Host details

Find out the following entries and change according to you installation directories and path

#define where jboss is - this is the directory containing directories log, bin, conf etc

#define the user under which jboss will run, or use 'RUNASIS' to run as the current user

#make sure java is in your path
#bind jboss services to a specific IP address - added by rasith

JBOSS_HOST=${JBOSS_HOST:-""} Note:[Either give FQDN of your server or IP Address]

Step10: set chkconfig to start jboss in different runlevel

#chkconfig --level 345 jboss on
Step11: Start Jboss and Verify whether it is running properly

#/sbin/service jboss start
You should be able to see jboss up and running at http:://
Use /sbin/service jboss start|stop|restart to start , stop and to restart jboss

Stept12: Restart your server and verify jboss is running automatically after the restart

There You Go !! A Well-settled JBoss on your Cute Linux Box.
Happy LinuXing !!

Sunday, October 18, 2009

Apache: How to configure Directory Indexing in Apache?

Edit the /etc/httpd/conf/httpd.conf file :

Just Look at the line starting:

[Please note: Do add lesser than sign in front of directory]
directory "/var/www/html/pdfs"

Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all


Restart the Apache.
Try browsing http://localhost/pdfs

Saturday, October 10, 2009

Sudo: How to provide access rights to a user?

The syntax of the file is pretty explanatory,



So if the username is 'eth1' and you want to provide access to the command /sbin/mount to the user then,


eth1 ALL=/sbin/mount

username ALL=NOPASSWD: /sbin/fdisk

Find out the path of command using

which fdisk or etc..

Also, You can also split the specifications up using User_Alias and Cmnd_Alias to make it a little easier to organize.
Here is a contrived example for ya'.

### User Aliases

## This is a list of users that have the ability to sudo the same commands.
User_Alias USERLST1=user1,user2

## This group has the ability to sudo the same commands.
## 'webadmgp' is a primary or secondary group that some of your users have.
User_Alias WEBGROUP=%webadmgp

### Command Aliases

## Storage
Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Networking
Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Webadmin
Cmnd_Alias WEBADMIN = /etc/rc.d/init.d/httpd

### The Commands Section

## The USERLST1 users (user1 and user2) can sudo all the commands listed in Cmnd_Alias STORAGE.
## They don't need to enter a password.


## The WEBGROUP users (every user that has 'webadmgp' as a primary or secondary group)
## can sudo all of the commands listed in the NETWORKING an WEBADMIN Cmnd_Alias lists.
## They don't need to enter a password either.

WEBGROUP ALL=NOPASSWD: NETWORKING,WEBADMINWhere things go doesn't seem to be important.

When you save the file, 'visudo' will tell you if you have a syntax error or some inconsistancy.

And be careful if you cut and paste into the file. If you cut a single long line that has wrapped on your screen, it'll paste in as multiple lines. When you file, 'visudo' will complain...

Friday, October 9, 2009

LVM: Deleting LVM Partition

I have a LVM Partitioned in such manner:

[root@ideathon ~]# df -h
Filesystem Size Used Avail Use% Mounted on
13G 3.4G 8.4G 29% /
/dev/cciss/c0d0p1 190M 15M 166M 8% /boot
none 3.9G 0 3.9G 0% /dev/shm
2.0G 65M 1.9G 4% /home/fstop
7.9G 158M 7.4G 3% /home/fstop/records
2.0G 44M 1.9G 3% /home/fstop/logs
1008M 77M 881M 8% /home/fstop/tomcat
58G 84M 56G 1% /home/fstop/mysql/data
20G 74M 19G 1% /home/fstop/mysql/logs
6.0G 45M 5.6G 1% /home/fstop/archive

Now What I want is: How to delete LVM partition?


Say, I want to remove the following LVM partition:

58G 84M 56G 1% /home/fstop/mysql/data

So I will follow the following commands:

#umount /home/fstop/mysql/data

It may run successfully but if it shows error like:

Cannot umount: device is busy

Then You need to run fuser command to kill the process held by some other processes.

Just running:

#fuser /home/fstop
/home/fstop: 28406c 28425c 28453c 28479c 28526c 28592c 28644c 28740c
#fuser -ku /home/fstop

Using the above switches you can kill the process which is holding the file and free the file/folders.

Try running df command again:

[root@ideathon ~]# df -h
Filesystem Size Used Avail Use% Mounted on
13G 3.4G 8.4G 29% /
/dev/cciss/c0d0p1 190M 15M 166M 8% /boot
none 3.9G 0 3.9G 0% /dev/shm
2.0G 65M 1.9G 4% /home/fstop
7.9G 158M 7.4G 3% /home/fstop/records
2.0G 44M 1.9G 3% /home/fstop/logs
1008M 77M 881M 8% /home/fstop/tomcat

20G 74M 19G 1% /home/fstop/mysql/logs
6.0G 45M 5.6G 1% /home/fstop/archive

(to be contd..)

Wednesday, October 7, 2009

Apache: Port-Based Virtual Hosts


You want to present different content for HTTP connections on different ports.


Explicitly list the port number in the declaration:
Listen 8080


Listen 9090

DocumentRoot /www/vhosts/port9090

Apache:Splitting Up a LogFile


Because of a large number of virtual hosts, you want to have a single logfile for all of them and split it up afterward.


LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost
CustomLog logs/vhost_log vhost

Then, after rotating your logfile:
split-logfile < logs/vhost_log

Saturday, October 3, 2009

Episode 21: Sendmail /etc/mail/virtusertable Setup?

File: /etc/mail/virtusertable finance

#cd /etc/mail

#makemap hash virtusertable.db < virtusertable #service sendmail restart File: /etc/mail/access

finance: azit,abhi,receiver

#service sendmail restart

Try out sending mail to
And Found mail to all the three Users:

[receiver@Innova ~]$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/receiver": 1 message 1 new
>N 1 Sun Oct 4 03:34 16/650 "hi"
& t
Message 1:
From Sun Oct 4 03:34:25 2009
Date: Sun, 4 Oct 2009 03:34:25 +0530
Subject: hi



Episode 20: How can I redirect mail to a different port on my smarthost?

If a system administrator does not want to use the default port 25 for SMTP traffic to a smarthost, it can be redirected by inserting this line into the file to change the port number:

define(`RELAY_MAILER_ARGS', `TPC $h XXXX')dnl

Replace XXXX with the desired port on the smarthost. The Sendmail service must be restarted after applying this change. Restart the service with:

service sendmail restart

Note: If for any reason, a restart of the mail server has to be avoided, the sendmail service can be reloaded instead by issuing the command:

service sendmail reload

Friday, October 2, 2009

Episode 19: How can I control whether incoming email is accepted, denied, or relayed when using Sendmail?

The file /etc/mail/access is used to accept, deny, or relay incoming email. This file controls access to users, entire domains, or an entire IP subnet. The first column specifies a user, domain, or subnet. The second column can be one of the following values:

rejects the sender with a general purpose message

accepts mail for receipt (not relay)

accept mail for relaying

discard the message completely (harsher than reject)

ERROR:550 your message
like REJECT but returns with your specific message

Here is an example /etc/mail/access file: REJECT REJECT
204.168.23 REJECT
192.168 OK RELAY ERROR:550 mail discarded
nobody@ ERROR:550 bad name

After making changes to this file, execute the following for the changes to take effect:

# make -C /etc/mail
# service sendmail restart

For Example:

I add the following entry in /etc/mail/access : REJECT
abhi ERROR:550 mail discarded
ajeet RELAY

Then I ran:
make -C /etc/mail
service sendmail restart

When I tried sending mail from user as:

[sender@Innova ~]$ echo "hello" | mail -v -s "hi" Connecting to [] via relay...
220 ESMTP Sendmail 8.14.2/8.14.2; Sat, 3 Oct 2009 17:39:59 +0530
>>> EHLO Hello localhost.localdomain [], pleased to meet you
250 HELP
>>> MAIL From: SIZE=47
250 2.1.0 ... Sender ok
>>> RCPT To:
>>> DATA
550 5.2.1 ... Mailbox disabled for this recipient
503 5.0.0 Need RCPT (recipient)
>>> RSET
250 2.0.0 Reset state
/home/sender/dead.letter... Saved message in /home/sender/dead.letter
Closing connection to []
>>> QUIT
221 2.0.0 closing connection

And When I tried :

[sender@Innova ~]$ echo "hello" | mail -v -s "hi" Connecting to [] via relay...
220 ESMTP Sendmail 8.14.2/8.14.2; Sat, 3 Oct 2009 18:46:32 +0530
>>> EHLO Hello localhost.localdomain [], pleased to meet you
250 HELP
>>> MAIL From: SIZE=47
250 2.1.0 ... Sender ok
>>> RCPT To:
>>> DATA
550 5.0.0 ... mail discarded
503 5.0.0 Need RCPT (recipient)
>>> RSET
250 2.0.0 Reset state
/home/sender/dead.letter... Saved message in /home/sender/dead.letter
Closing connection to []
>>> QUIT
221 2.0.0 closing connection
[sender@Innova ~]$

So Both the receiver and abhi were discarded but when I tried mailing ajeet
it went successful.

[sender@Innova ~]$ echo "hello"|mail -v -s "I am here" Connecting to [] via relay...
220 ESMTP Sendmail 8.14.2/8.14.2; Sat, 3 Oct 2009 18:54:29 +0530
>>> EHLO Hello localhost.localdomain [], pleased to meet you
250 HELP
>>> MAIL From: SIZE=51
250 2.1.0 ... Sender ok
>>> RCPT To:
>>> DATA
250 2.1.5 ... Recipient ok
354 Enter mail, end with "." on a line by itself
>>> .
250 2.0.0 n93DOTF2006201 Message accepted for delivery Sent (n93DOTF2006201 Message accepted for delivery)
Closing connection to []
>>> QUIT
221 2.0.0 closing connection
[sender@Innova ~]$

So It is working for ajeet.

Episode 18: How can I make new aliases for my users if I am running sendmail?

Edit the /etc/aliases file. The syntax for the file is as follows:

username: newalias

Add the usernames and aliases then save the file. Then run (as the user root) the following command:


Or restart sendmail with this command:

service sendmail restart

This is the same as running the following command:

sendmail -bi

The aliases database will now be rebuilt with the new changes.

Episode 17: How do I masquerade a server's mail address on sendmail with domaintable?

To masquerade a server's domainname from one name to another use the domaintable FEATURE of sendmail.

First, open the file /etc/mail/domaintable for editing. The structure of this file is:

For example:

# vi /etc/mail/domaintable

So mail for would process as

Next, add the following entry to /etc/mail/ file:


Next, remake the file:

# cd /etc/mail
# make

Then, restart the sendmail service:

# service sendmail restart

Episode 16: Is it possible to have 2 or more SMART_HOST's configured for redundancy in Sendmail?

It is possible to set up multiple smart hosts in Sendmail. The syntax required in the /etc/mail/ file is:

define(SMARTHOST `[]:[]:[]')

The square brackets are to ensure that Sendmail does not do a Domain Name Service MX lookup. After editing the /etc/mail/ file, the /etc/mail/ file must be regenerated.

For Red Hat Enterprise Linux 2.1, use:

m4 /etc/mail/ > /etc/

For Red Hat Enterprise Linux 3, use:

make -C /etc/mail

Note: If you are running a Domain Name Server (DNS), an alternative to specifying multiple smart hosts is to set up your DNS server to have multiple MX records under the smart host's host name and have the DNS server 'round robin' the MX records. This configuration, however, is out the scope of this Knowledgebase article

Episode 15: Why do I get the error 'can not chdir(/var/spool/clientmqueue/): Permission denied' when restarting Sendmail?

You should first check the permissions on the following files:

# ls -l /usr/sbin/sendmail.sendmail
-r-xr-sr-x root smmsp /usr/sbin/sendmail.sendmail

# ls -l /var/spool
drwxrwx--- smmsp smmsp /var/spool/clientmqueue

If your permissions are mis-matched, you can modify them by doing the following:

# chown root.smmsp /usr/sbin/sendmail.sendmail
# chmod g+s /usr/sbin/sendmail.sendmail
# chown smmsp.smmsp /var/spool/clientmqueue

After changing permissions, you need to restart the Sendmail service, type:

# service sendmail restart

More information is available at:

•Hints how to configure and run Sendmail

Episode 14: Sendmail Masquerade

Masquerading is a feature which rewrites the hostname in the address of outbound mails. This feature is usually applied to route the inbound mail from a network through a centralized mail hub. This feature is also applied to hide the actual hostname in order to manage mails to avoid using a busy hostname.

To enable this, add the following lines to the /etc/mail/ file:


Update the Sendmail configuration files using the m4 macro processor to generate a new file by executing the following command:

# m4 /etc/mail/ > /etc/mail/

To get the Sendmail macro file, the sendmail-cf package must be installed on the system.

After creating a new /etc/mail/ file, restart Sendmail for the changes to take effect. To do this, use the following command:

# service sendmail restart

For more details on the masquerading of Sendmail, use the following links:

•Red Hat Documentation:

•Sendmail - Masquerading and Relaying:

Episode 13: How do I configure sendmail to receive mail for multiple domains?

This can be accomplished by adding the domains you wish to receive mail for in the /etc/mail/local-host-names file. It is important that the sendmail server can resolve these domain names through DNS.



# local-host-names - include all aliases for your machine here.

Episode 12: How do I configure sendmail to route mail to specific hosts?

This can be accomplished by adding appropriate entries to the /etc/mail/mailertable file. This file allows you to specify a domain, and where you want all email for that domain sent to. In the example below, all email destined for will be automatically forwarded to a mail server that resolves to backend.mail.server. Additionally, all email received from the network will be forwarded to a mail server that resolves to outbound.mail.server.


/etc/mail/mailertable smtp:backend.mail.server
192. smtp:outgoing.mail.server

After your modifications to /etc/mail/mailertable are complete you will need to run the following command:

makemap hash /etc/mail/mailertable.db < /etc/mail/mailertable

Then restart sendmail: service sendmail restart

Episode11: Can sendmail be used without DNS?

There are a number of steps required to successfully use sendmail when there is limited or no DNS.

•Setting a SMARTHOST

◦Ensure the required host is resolvable, either by /etc/hosts or DNS, or alternatively specify an IP address.

◦Use line in /etc/mail/ that resembles define(`SMART_HOST',`')dnl

•Since the system implicitly have limited resolving capabilities, accept email for unknown domains

◦Use line in /etc/mail/ of the form FEATURE(accept_unresolvable_domains)dnl

•Ensure that the ServiceSwitchFile (by default at /etc/mail/service.switch) has content similar to:

aliases files
hosts files

•Setting the submission agent to ignore DNS

◦Use line in /etc/mail/ of the form define(`confDIRECT_SUBMISSION_MODIFIERS',`C')

◦Use line in /etc/mail/ of the form FEATURE(accept_unresolvable_domains)dnl

Having completed the above changes remake the & by typing make in /etc/mail

The daemon may also need to be restarted with the command:

# service sendmail restart

Episode 10: Sendmail server to forward mail to an internal backup mail server?

In order to do this you must define two options in your /etc/mail/ file:

define(`MAIL_HUB', `hostname')

In the above options, "hostname" is the hostname of the backup mail server. After you have added those options, you need to execute the commands:

make -C /etc/mail
service sendmail restart

These commands will rebuild the Sendmail macro configuration file for m4 and then restart the Sendmail service, respectively.

Note: This configuration should also work if the internal backup server is a Microsoft Exchange mail server

Episode 9: How do I setup a Sendmail server to forward all mail to a different mail server?

First, you setup the mail server to allow connections from other systems. Change the following line in the /etc/mail/ file:

DAEMON_OPTIONS(`Port=smtp,Addr=, Name=MTA')dnl


DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl

Add the following line to the /etc/mail/ file:

define('SMART_HOST', 'hostname')

Where hostname is the hostname or the IP address of the other mail server. Next, rebuild your m4 macros and restart Sendmail. Execute the commands:

make -C /etc/mail
service sendmail restart

All mail sent to the primary mail server will forward mail to the server defined in the Smart Host option

Episode 8: Why does sendmail does not use NIS mail.aliases?

By default sendmail honors aliases defined only in /etc/aliases. To honor NIS mail.alaises map, edit the file /etc/mail/

Change the following line:


define(`ALIAS_FILE', `/etc/aliases')dnl



For example, if the domain name is, the file may look like this:


It may also look like this:


Episode 7: Sendmail to deliver mail in an NIS environment without DNS?

Create a file called /etc/mail/service.switch and include the following in the file:

hosts nis files

Restart Sendmail using service sendmail restart as root. This should resolve the issue

Episode 6: Sendmail Not Listening to Local Domain but working for other Domain..

There had been changes to the way Sendmail handles email from previous versions. Previously, Sendmail will connect directly to the receiving Mail Transport Agent (MTA). It is possible, at that point, not to run the Sendmail daemon but still be able to send emails. In Red Hat Enterprise Linux 3 and later, Sendmail runs 2 daemons: one to listen on localhost to queue the mail and one to actually send the mail.

In some configurations, Sendmail uses a smart host to relay outgoing emails. For security purposes, it is also sometimes configured not to run as a daemon process. This configuration works fine in Red Hat Enterprise Linux 2.1 but not in Red Hat Enterprise Linux 3 and later. If Sendmail does not listen on the localhost, emails to the local system will be deferred. Below is a sample log of what happens:

Jun 27 11:28:46 localhost sendmail[3272]: j5R1SktO003272: from=root, size=37, class=0, nrcpts=1, msgid=<>, relay=root@localhost
Jun 27 11:28:46 localhost sendmail[3272]: j5R1SktO003272: to=joe, ctladdr=root (0/0), delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=30037, relay=[] [], dsn=4.0.0, stat=Deferred: Connection refused by []

Using ps ax | grep sendmail to check if Sendmail is running would give the following output:

3240 ? Ss 0:00 sendmail: Queue runner@01:00:00 for /var/spool/mqueue
3246 ? Ss 0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue


To correct this problem, it is necessary that Sendmail listens on localhost. Make sure that /etc/sysconfig/sendmail is configured with the option:


After making any changes, restart Sendmail by running this command:

service sendmail restart

Verifying with ps ax | grep sendmail should show something similar to this:

2387 ? Ss 4:31 sendmail: accepting connections
2393 ? Ss 0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue

Episode 5: Block specific sender to specific recipient ..

Issue: I'm trying to configure our mail server to block email from a specific sender reaching a specific recipient. In other words, if one of our employees is getting harassed by a 'stalker', how would one go about blocking, at the MTA (Sendmail) level, a specific sender email address from reaching a particular users inbox? We do not want to capture the email - simply block it before it consumes server resources.

The Sendmail server (MTA) is a front end to our Exchange server so no user accounts exist on the Linux server. We simply use it as a SPAM and Virus scanner then forward clean email to the Exchange server.

Any and all help appreciated


I read the Sendmail, 3rd Edition book and resolved the issue.

Mainly, I had to add

in the /etc/mail/ file

Then I had to create the following entries<@> DISCARD
in /etc/mail/access file

Episode 4: Sendmail Local Mailbox Commands..

In the Last Episode we went through few Sendmail Masquerading stuffs,this time we will be exploring Local users malbox commands in details:

Say, There are Two users: Sender and Receiver.Sendmail is configured properly. Let us run this command logging in as sender:

[sender@Innova ~]$ echo " Hello" | mail -v -s "hi" receiver@localhost
receiver@localhost... Connecting to [] via relay...
220 ESMTP Sendmail 8.14.2/8.14.2; Sat, 3 Oct 2009 14:26:02 +0530
>>> EHLO Hello localhost.localdomain [], pleased to meet you
250 HELP
>>> MAIL From: SIZE=43
250 2.1.0 ... Sender ok
>>> RCPT To:
>>> DATA
250 2.1.5 ... Recipient ok
354 Enter mail, end with "." on a line by itself
>>> .
250 2.0.0 n938u2nS005377 Message accepted for delivery
receiver@localhost... Sent (n938u2nS005377 Message accepted for delivery)
Closing connection to []
>>> QUIT
221 2.0.0 closing connection
[sender@Innova ~]$

A Mail has been sent to receiver in the same machine.
Let us now check if the mail has actually been received by user called receiver or not.

[receiver@Innova ~]$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/receiver": 1 message 1 unread
>U 1 Sat Oct 3 14:26 17/674 "hi"

Yes It shows that receiver has received the mail.
Let us try out with other commands:

Type ? after & above and it will display lots of options:

[receiver@Innova ~]$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/receiver": 1 message 1 unread
>U 1 Sat Oct 3 14:26 17/674 "hi"
& ^CInterrupt
& ?
Mail Commands
t type messages
n goto and type next message
e edit messages
f give head lines of messages
d delete messages
s file append messages to file
u undelete messages
R reply to message senders
r reply to message senders and all recipients
pre make messages go back to /usr/spool/mail
m mail to specific users
q quit, saving unresolved messages in mbox
x quit, do not remove system mailbox
h print out active message headers
! shell escape
cd [directory] chdir to directory or home if none given

A consists of integers, ranges of same, or user names separated
by spaces. If omitted, Mail uses the last message typed.

A consists of user names or aliases separated by spaces.
Aliases are defined in .mailrc in your home directory.

Let us see the mail sent by sender through this command:

Option 1:

& t sender
Message 1:
From Sat Oct 3 14:26:02 2009
Date: Sat, 3 Oct 2009 14:26:02 +0530
Subject: hi



So Sender has simply sent "hello" Message with subjectline "hi".

Option 2:

Lets see another option to check new mail if any.

& n

Option 3:

& f sender
> 1 Sat Oct 3 14:26 17/674 "hi"

Option 4:

& R sender
Subject: Re: hi

I have received your mail Dude
& q
Saved 1 message in mbox

Episode 3: Using Sendmail to Change the Sender's Email Address

1) Add these statements to your /etc/mail/ file to activate the feature:

FEATURE(`genericstable',`hash -o /etc/mail/genericstable.db')dnl

2) Create a /etc/mail/generics-domains file that is just a list of all the domains that should be inspected. Make sure the file includes your server's canonical domain name, which you can obtain using the command:

[root@Innova ~]# sendmail -bt -d0.1
> You have new mail in /var/spool/mail/root
[root@Innova ~]#

Here is a sample /etc/mail/generics-domains file:
[root@Innova ~]# cat /etc/mail/generics-domains

3) Create your /etc/mail/genericstable file. First sendmail searches the /etc/mail/generics-domains file for a list of domains to reverse map. It then looks at the /etc/mail/genericstable file for an individual email address from a matching domain. The format of the file is


Run m4 command followed by service restart for the sendmail to work.
This time if you send mail as:

[mailadmin ~]$ echo "hello" | mail -v -s "hello"

The Mail will arrive as: and not

Episode 2: Sendmail Troubleshooting


You are not able to send/receive mail due to Domain Name Issue.


Add to and Restart the sendmail service.

Dont forget to add this line to /etc/hosts: mailw

Hope it will solve the domain name issue.

Episode 1: Sendmail Masquerading


You want to receive mail as and not as under Sendmail configuration.


Add this entry in file:


By default, user "root" will not be masqueraded. To remove this restriction use:

command in /etc/mail/ You can comment this out if you like with a "dnl" at the beginning of the line and running the sendmail start script.

Run m4 command and restart the Sendmail.

Do Remember to add:

to file.