Saturday, November 13, 2010

Postfix records in maillog have time stamps from different time zones

SkyHi @ Saturday, November 13, 2010

Symptoms

If you look at /usr/local/psa/var/log/maillog, you may find your postfix/smtpd time stamp is switched by several hours:

Feb 15 05:24:33 server postfix/smtpd[11984]
Feb 15 14:24:44 server postfix/smtpd[12001]
Feb 15 05:24:44 server postfix/smtpd[11984]
Feb 15 05:24:44 server postfix/smtpd[12001]
Feb 15 14:24:45 server before-remote[12000]

Resolution

It is compounded by the fact that a part of Postfix processes, for security reasons, runs in chrooted environment and /etc/localtime is not accessible for them, so that records are written into maillog with UTC time zone.

To resolve the issue create directory /var/spool/postfix/etc :
# mkdir /var/spool/postfix/etc

and copy file /etc/localtime to that directory:
# cp /etc/localtime /var/spool/postfix/etc/

Then restart mail service.

Additional information

This issue affects only Postfix on RPM-based systems. Script /etc/init.d/postfix on Debian GNU/Linux copies necessary files on start. 
 
REFERENCES
http://kb.parallels.com/8082

Postfix Backup MX eMail Server Anti-Spam Configuration

SkyHi @ Saturday, November 13, 2010
According to RFC2821 the lowest-numbered records are the most preferred MX for domain. So I've a target Postfix backup server to keep the messages in a queue waiting for the primary server to become available. This ensures that if my primary MX goes down I do not loss any emails. However, spammers are connecting to my backup MX to avoid anti spam filters that are running on the primary MX server. This also hides their real IP from my primary MX. How do I configure anti-spam for my backup RHEL / CentOS 5.3 based Postfix mx server?

This is well known issue. Make sure your backup MX runs the same config in terms of spam rejection as your primary server. Try the following to improve backup eMail server anti spam configuration.
If the backup MX acts as a store-and-forward mail server

Consider the following example:

nixcraft.com. 86400 IN MX 10 mx01.nixcraft.net.in.
nixcraft.com. 86400 IN MX 20 mx02.nixcraft.net.in.

nixcraft.com email handled by two email servers. mx02.nixcraft.net.in is your backup server. Open main.cf and append the following restrictions on mx02.nixcraft.net.in.
Only allow your own domain to accept email

Use relay_domains to relay email for two domain called nixcraft.com and cyberciti.com. Also, set lookup tables with all valid addresses in the domains that match $relay_domains i.e. only accept email for valid email address.
# vi /etc/postfix/main.cf
Modify settings as follows:

relay_domains = nixcraft.com, cyberciti.com, $mydestination
relay_recipient_maps = hash:/etc/postfix/relay_recipients

Create /etc/postfix/relay_recipients to accept email for vivek@nixcraft.com, vivek@cyberciti.com, user3@nixcraft.com and so on..

vivek@nixcraft.com OK
vivek@cyberciti.com OK
user3@nixcraft.com OK

Save and close the file. Finally, update your db:
# postmap hash:/etc/postfix/relay_recipients
Anti spam via RBL

Now, add following lines main.cf to check spammer IP address using RBLs. Reject all email if they do not have a valid hostname or proper email address:

smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unauth_destination,
reject_unauth_pipelining,
reject_invalid_hostname,
reject_rbl_client zen.spamhaus.org
# helo required
smtpd_helo_required = yes
# disable vrfy command
disable_vrfy_command = yes

smtpd_data_restrictions =
reject_unauth_pipelining,
permit

Save and close the file. Restart / reload postfix:
# service postfix reload
There are other anti UCE settings, see Postfix anti UCE cheat sheet for more information.
Nolisting mx A entry

Spammers email software does not retry higher-priority MX records. So all you have to do is create a non-existent primary mail server and a working secondary mail server, attempts to contact the primary mail server will always fail. This technique uses a non-existent primary mail server, which is compatible with all correctly configured mail servers such as Sendmail, MS-Exchange, Postfix, Qmail, Exim etc. Create BIND dns configuration as follows:

nixcraft.com. 86400 IN MX 10 mx01.nixcraft.net.in.
nixcraft.com. 86400 IN MX 20 mx02.nixcraft.net.in.
nixcraft.com. 86400 IN MX 30 mx03.nixcraft.net.in.
nixcraft.com. 86400 IN MX 40 mx04.nixcraft.net.in.

Where,

* mx02.nixcraft.net.in - Runs your actual primary MX with anti spam and anti virus configurations.
* mx03.nixcraft.net.in - Your backup mx server with anti spam / virus and act as store and forward server for mx02.nixcraft.net.in.
* mx01.nixcraft.net.in and mx04.nixcraft.net.in are nolist MX servers. They can either be dead (or point to non existing IP) or you can run SMTP on port 25 that always returns 4xx error so that legitimate MTA to retry on a lower numbered MX server. nolist MX servers can also used to get more information about spammers to blacklist them. Google for "spam filtering services that offer free nolist servers" specifically for botnet data harvesting.

Greylisting Backup MX

Postfix can be configured to temporarily reject any email from a sender it does not recognize. If the mail is legitimate, the originating server will try again and the email is accepted. If the mail is from a spammer it will probably not be retried since a spammer goes through thousands of email addresses and cannot afford the time delay to retry. See how to configure postfix greylist policy server.
Spamassassin+Amavis+Clamd For Backup MX Server

Spamassassin is open source mail filter, to identify spam using a wide range of heuristic tests on mail headers and body text. You can install Spamassassin spam checking on your backup server. Emails found to be Spam (with higher spam score) will be drop out before reaching your primary email server. You can also use Clamav / Amavis to scan email and drop or forward infected emails. Install spamassassin, clamd and amavisd-new using yum or apt-get commands (turn on EPEL repo under RHEL / CentOS to install the following packages):
# yum install clamav-server amavisd-new spamassassin

* clamav-server : Clam Antivirus scanner server
* amavisd-new : amavisd-new is a high-performance and reliable interface between Postfix and virus scanners, and/or
Mail::SpamAssassin Perl module.
* spamassassin : Spam filter for email which can be invoked from mail delivery agents or in our case via amavisd-new

Once done, add as the following to your /etc/postfix/main.cf:

content_filter=smtp-amavis:[127.0.0.1]:10024

Save and close the file. Open /etc/postfix/master.cf and add the following settings:

smtp-amavis unix - - n - 2 smtp
-o smtp_data_done_timeout=2400
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20
127.0.0.1:10025 inet n - n - - smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks_style=host
-o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_address_mappings

Save and close the file. Also, update /etc/amavisd/amavisd.conf with required settings.

$daemon_user = 'amavis'; # (no default; customary: vscan or amavis), -u
$daemon_group = 'amavis'; # (no default; customary: vscan or amavis), -g
$mydomain = 'nixcraft.net.in'; # a convenient default for other settings
$log_level = 1; # verbosity 0..5, -d
$DO_SYSLOG = 1; # log via syslogd (preferred
$inet_socket_port = 10024; # listen on this local TCP port(s) (see $protocol)
$sa_tag_level_deflt = -999; # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 6.31; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 6.31; # triggers spam evasive actions
$sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent
$virus_admin = 'postmaster\@nixcraft.net.in'; # notifications recip.
$mailfrom_notify_admin = 'postmaster\@nixcraft.net.in'; # notifications sender
$mailfrom_notify_recip = 'postmaster\@nixcraft.net.in'; # notifications sender
$mailfrom_notify_spamadmin = 'postmaster\@nixcraft.net.in'; # notifications sender
$mailfrom_to_quarantine = 'postmaster\@nixcraft.net.in'; # null return path; uses original sender if undef
$sa_spam_subject_tag = '***SPAM*** ';
$myhostname = 'mx02.nixcraft.net.in'; # must be a fully-qualified domain name!
$notify_method = 'smtp:[127.0.0.1]:10025';
$forward_method = 'smtp:[127.0.0.1]:10025'; # set to undef with milter!
# add your server public ip, private ip,
@inet_acl = qw( 203.1.2.3 127/8 10.10.29.11);

Save and close the file. Update spamassassin settings in /var/spool/amavisd/:
# usermod -s /bin/bash amavis
# passwd amavis
# su - amavis
$ razor-admin -discover
$ razor-admin -create
$ razor-admin -register -l -user=vivek@nixcraft.co.in -pass=somePassword
$ cd .spamassassin
$ cp /usr/share/spamassassin/user_prefs.template user_prefs
$ exit
# usermod -s /sbin/nologin amavis
Update /etc/clamd.d/amavisd.conf as follows:

# Use system logger.
LogSyslog yes

# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
LogFacility LOG_MAIL

# This option allows you to save a process identifier of the listening
# daemon (main thread).
PidFile /var/run/amavisd/clamd.pid

# Remove stale socket after unclean shutdown.
# Default: disabled
FixStaleSocket yes

# Run as a selected user (clamd must be started by root).
User amavis

# Path to a local socket file the daemon will listen on.
LocalSocket /var/spool/amavisd/clamd.sock

Update /etc/mail/spamassassin/local.cf as follows:

required_hits 6.31
report_safe 1
rewrite_subject 0
# Enable the Bayes system
use_bayes 1
# Enable Bayes auto-learning
auto_learn 1

Save and close the file. Finally, restart postfix and other services:
# service clamd.amavisd start
# service amavisd start
# service postfix restart
Turn services on boot:
# chkconfig clamd.amavisd on
# chkconfig amavisd on
# chkconfig postfix on
Now, check your /var/log/maillog for any errors or details:
# netstat -tulpn -A inet| egrep ':25|:1002?'
# tail -f /var/log/maillog
Above configuration will open the following ports on server:

1. 10024 - Amavisd
2. 10025 - Amavisd will communicate back the results to Postfix
3. 25 - SMTP Port

A note about same priority mx servers

You can point the mail servers, all with the same priority. It offers the following benfits:

* Load balancing
* Centralized user mail managment via LDAP or MySQL / PGSQL
* Centralized virus scanning
* Centralized Spam scanning

Sample dns records:

nixcraft.com. 86400 IN MX 10 mx01.nixcraft.net.in.
nixcraft.com. 86400 IN MX 10 mx02.nixcraft.net.in.
nixcraft.com. 86400 IN MX 10 mx03.nixcraft.net.in.
; imap server
imap 86400 IN A 202.54.1.2
; pop3 server - can be CNAME too
pop3 86400 IN A 202.54.1.2

You may need additional servers inside your lan:

* MySQL/OpenLDAP (10.24.116.2) - Store user name, email, mailbox and other information.
* Central anti virus server (10.24.116.3) - Used by all your mx servers for scanning using TCP/IP. You can also do the same for spam scanning using TCP/IP.

Each mx server can use centralized anti spam and anti-virus server. Once scanned Postfix can deliver final mail which can be retrieved using POP3 / IMAP server.
Further Readings / References :

This FAQ assumed that you have working Postfix primary and backup server. It only covered anti spam related topics. For further details refer the following urls and respective man pages:

* Postfix
* Spamassassin
* Clamd
* Amavisd
* Bind
* Wikipedia articles about NOListing and MX record

REFERENCES
http://www.cyberciti.biz/faq/postfix-backup-mx-server-anti-spam/

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

SkyHi @ Saturday, November 13, 2010
Q. How do you set-up SSH with DSA public key authentication? 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?

A. 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
Output:

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/id_dsa.pub.
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/id_dsa.pub.
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/id_dsa.pub on Machine #1 (tom) to remote server jerry as ~/.ssh/authorized_keys:
$ scp ~/.ssh/id_dsa.pub 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 user@remote-server.com
$ 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
Output:

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
OR
$ /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.


Install / Append SSH Key In A Remote Linux / UNIX Servers Authorized_keys

by Vivek Gite on May 6, 2010 · 4 comments

How do I install my SSH public key ~/.ssh/id_rsa.pub onto a remote Linux / UNIX server automatically from Linux workstation / Apple OS X laptop without using scp and/or copy & paste method?

You need to use the ssh-copy-id script that uses ssh to log into a remote machine using a login password. The syntax is as follows:

ssh-copy-id -i ~/.ssh/id_rsa.pub user@server.example.com
ssh-copy-id -i ~/.ssh/id_dsa.pub user@server.example.com

Step # 1: Create Keys

Type the following ssh-keygen command to generates, manages and converts authentication keys for your workstation / laptop:
ssh-keygen
Make sure you protect keys with the passphrase.
Step # 2: Install Keys

Install key in a remote server called www-03.nixcraft.in, enter:
ssh-copy-id -i ~/.ssh/id_dsa.pub username@www-03.nixcraft.in
Step #3: Use keychain for password less login

OpenSSH offers RSA and DSA authentication to remote systems without supplying a password. keychain is a special bash script designed to make key-based authentication incredibly convenient and flexible. Add following lines to your ~/.bash_profile

/usr/bin/keychain $HOME/.ssh/id_rsa
source $HOME/.keychain/$HOSTNAME-sh

Save and close the file.
References:

* man ssh-copy-id


REFERENCES
http://www.cyberciti.biz/faq/ssh-password-less-login-with-dsa-publickey-authentication/
http://www.cyberciti.biz/faq/install-ssh-identity-key-remote-host/

keychain: Set Up Secure Passwordless SSH Access For Backup Scripts

SkyHi @ Saturday, November 13, 2010
We establish connections to remote systems without supplying a password, however I do not want to store my password less keys ( passphrase-free keys) on my servers. ssh-agent, takes care of keys with passphase, which allowing me to easily have ssh-agent process per system per login session. How do I dramatically reduces the number of times I've to punch my passphrase from once per new login session to once every time my local server is rebooted? How do I use keychain utility for all my backup scripts for secure passwordless login?

OpenSSH offers RSA and DSA authentication to remote systems without supplying a password. keychain is a special bash script designed to make key-based authentication incredibly convenient and flexible. It offers various security benefits over passphrase-free keys.

How Does Keychain Make It Better Than a Key Less Passphrase?

If attacker broken into server with passphrase-free keys, all other your servers / workstation on which keys are used are also security risk (they can be easily breached). With keychain or ssh-agent attacker won't able to touch your remote systems without breaking your passphrase. Another example, if your laptop or harddisk stolen, an attacker can simply copy your key and use it anywhere as it is not protected by a passphrase.
keychain is a manager for ssh-agent, typically run from ~/.bash_profile. It allows your shells and cron jobs to share a single ssh-agent process. By default, the ssh-agent started by keychain is long-running and will continue to run, even after you have logged out from the system. If you want to change this behavior, take a look at the --clear and --timeout options, described below. Our sample setup is as follows:
peerbox.nixcraft.net.in => Remote Backup Server. Works in pull only mode. It will backup server1.nixcraft.net.in and server2.nixcraft.net.in.
vivek-desktop.nixcraft.net.in => My desktop computer.
server1.nixcraft.net.in => General purpose remote server.
server2.nixcraft.net.in => General purpose remote web / mail / proxy server.
Install keychain software on peerbox.nixcraft.net.in so that it can login securely to other two servers for backup.

Install keychain on CentOS / RHEL / Fedora Linux

You need RPMForge repo enabled to install keychain package.
# yum install keychain

Install keychain on Debian / Ubuntu Linux

# apt-get update && apt-get install keychain

Install keychain on FreeBSD

# portsnap fetch update
# cd /usr/ports/security/keychain
# make install clean

How Do I Setup SSH Keys With passphrase?

Simply type the following commands:
$ ssh-keygen -t rsa
OR
$ ssh-keygen -t dsa
Assign the pass phrase when prompted. See the following step-by-step guide for detailed information:
  1. Howto Linux / UNIX setup SSH with DSA public key authentication (password less login)
  2. Howto use multiple SSH keys for password less login

How Do I Use Keychain?

Once OpenSSH keys are configured with a pass phrase, update your $HOME/.bash_profile file which is your personal initialization file, executed for login BASH shells:
$ vi $HOME/.bash_profile
Append the following code:
### START-Keychain ###
# Let  re-use ssh-agent and/or gpg-agent between logins
/usr/bin/keychain $HOME/.ssh/id_dsa
source $HOME/.keychain/$HOSTNAME-sh
### End-Keychain ###
Now you've keychanin configured to call keychain tool every login. Just log out and log back in to server from your desktop to test your setup:
$ ssh root@www03.nixcraft.net.in
Sample Output:
Fig.01 - Keychain in Action
Fig.01 - Keychain in Action
keyhcain is up and running. Now, all you have to do is append your servers key file $HOME/.ssh/id_dsa.pub to other UNIX / Linux / BSD boxes:
# scp $HOME/.ssh/id_dsa.pub server1.nixcraft.net.in:~/pubkey
# scp $HOME/.ssh/id_dsa.pub server2.nixcraft.net.in:~/pubkey
# ssh server1.nixcraft.net.in cat ~/pubkey >> ~/.ssh/authorized_keys2; rm ~/pubkey
# ssh server2.nixcraft.net.in cat ~/pubkey >> ~/.ssh/authorized_keys2; rm ~/pubkey
# ssh root@server1.nixcraft.net.in
# ssh user@server2.nixcraft.net.in

Task: Clear / Delete All Of Ssh-agent's Key

# keychain --clear

Security Task: Make Sure Intruder Cannot Use Your Existing SSH-Agent's Keys (only allow cron jobs to use password less login)

The idea is pretty simply only allow backup shell scripts and other cron job to do password less login but all users including an intruder must provide a passphrase-key for interactive login. This is done by deleting all of ssh-agent's keys. This option will increases security, it still allows your cron jobs to use your ssh keys when you're logged out. Update your ~/.bash_profile as follows:
/usr/bin/keychain --clear $HOME/.ssh/id_dsa
If you are using RSA, use:
/usr/bin/keychain --clear $HOME/.ssh/id_rsa
Now, just log in to remote server box once :
$ ssh root@peerbox.nixcraft.net.in
Log out (only grant access to cron jobs such as backup)
# logout

Task: Use Keychain With Backup Scripts for Passwordless login via cron

Add the following before your rsync, tar over ssh or any other network backup command:
source $HOME/.keychain/$HOSTNAME-sh
Here is a sample rsync script:

#!/bin/bash
# Remote Server Rsync backup Replication Shell Script
# Local dir location
LOCALBAKPOINT=/iscsi
LOCALBAKDIR=/backups/server1.nixcraft.net.in/wwwroot
# Remote ssh server setup
SSHUER=root
SSHSERVER=server1.nixcraft.net.in
SSHBACKUPROOT=/wwwroot
 
# Make sure you can log in to remote server without a password
source $HOME/.keychain/$HOSTNAME-sh 
 
# Make sure local backup dir exists
[ ! -d ${LOCALBAKPOINT}${LOCALBAKDIR} ] && mkdir -p ${LOCALBAKPOINT}${LOCALBAKDIR}
 
# Start backup
/usr/bin/rsync --exclude '*access.log*' --exclude '*error.log*' -avz -e 'ssh ' ${SSHUER}@${SSHSERVER}:${SSHBACKUPROOT} ${LOCALBAKPOINT}${LOCALBAKDIR}
 
# See if backup failed or not to /var/log/messages file
[ $? -eq 0 ] && logger 'RSYNC BACKUP : Done' || logger 'RSYNC BACKUP : FAILED!'


If you are using rsnaphot backup server (see how to setup RHEL / CentOS / Debian rsnapshot backup server) add the following to your /etc/rsnapshot.conf file
# Get ssh login info via keychain
cmd_preexec    source /root/.keychain/hostname.example.com-sh

Final Note About Keychain and Security

  • Cracker with an advanced attacking with deadly coding skills can still get key from memory. However, keychain makes it pretty difficult for normal users and attackers to steal your keys and use it.
  • OpenSSH sshd server offers two additional options to protect abuse of keys. First, make sure root login disabled (PermitRootLogin yes). Second, specify which user accounts on the server are allowed to be used for authentication by adding AuthorizedKeysFile %h/.ssh/authorized_keys_FileName. See sshd_config man page for further details.

Suggested Readings:

CentOS: Install Packages Via yum Command Using DVD / CD as Repo

SkyHi @ Saturday, November 13, 2010
How do I install packages via DVD / CD using yum command under CentOS Community Enterprise Linux version 5.x?

CentOS Linux comes with CentOS-Media.repo which is used to mount the default locations for a CDROM / DVD on CentOS-5. You can use this repo and yum to install items directly off the DVD ISO that we release. Open /etc/yum.repos.d/CentOS-Media.repo file, enter:
# vi /etc/yum.repos.d/CentOS-Media.repo
Make sure enabled is set to 1:
enabled=1
Save and close the file. To use repo put your DVD and along with the other repos, enter:
# yum --enablerepo=c5-media install pacakge-name
To only use the DVDmedia repo, do this:
# yum --disablerepo=\* --enablerepo=c5-media install pacakge-name
OR use groupinstall command
# yum --disablerepo=\* --enablerepo=c5-media groupinstall 'Virtualization'

See Also:

RHEL 5.x user can use the following tutorial to install files from DVD / CD using yum:
  1. Howto Setup yum repositories to update or install package from ISO CDROM Image



Howto Setup yum repositories to update or install package from ISO CDROM Image

by Vivek Gite · 24 comments
yum (Yellow dog Updater Modified) is a package manager for RPM compatible Linux systems such as CentOS, Fedora core and latest Redhat Enterprise Linux.
So how do you use yum to update / install packages from an ISO of CentOS / FC / RHEL CD?
Creation of yum repositories is handled by a separate tool called createrepo, which generates the necessary XML metadata. If you have a slow internet connection or collection of all downloaded ISO images, use this hack to install rpms from iso images.

Step # 1: Mount an ISO file

Type the following command (replace iso file name with the actual iso file):
# yum install createrepo
# mkdir -p /mnt/iso/{1,2,3}
# mount -o loop /path/to/centos1.iso /mnt/iso/1

Step # 2: Create a repository

Use createrepo to generate the necessary XML metadata. Type the following commands:
# cd /mnt/iso
# createrepo .

Clean repo, enter:
# yum clean all

Step # 3: Create config file

You need to create a repo config file in /etc/yum.repos.d/ directory.
# vi /etc/yum.repos.d/iso.repo
Append following text:
[My ISO Repository]
baseurl=file:///mnt/iso
enabled=1

Save and close the changes.
Now use yum command to install packages from ISO images:
# yum install package-name


REFERENCES
http://www.cyberciti.biz/faq/centos-linux-install-packages-from-dvd-using-yum/
http://www.cyberciti.biz/tips/redhat-centos-fedora-linux-setup-repo.html

Iptables Open VNC Port To Allow Incoming VNC Connections

SkyHi @ Saturday, November 13, 2010
How do I configure Linux system firewall to allow incoming VNC connections?

VNC server listens on the following TCP ports:
=> VNC server on display 0 will listen on TCP ports 5800, 5900 and 6000
=> VNC server on display 1 will listen on TCP ports 5801, 5901 and 6001
=> VNC server on display N will listen on TCP ports 580N, 590N and 600N
In other words a VNC server listens for a VNC client on TCP ports 5800+N, 5900+N, and 6000+N where N is the display which starts at zero. So,
  • 5800+N - Java-based vncviewer;
  • 5900+N - VNC Client Port;
  • 6000+N - X Server port.

Find Out VNC Port

Type the following command:
# netstat -tulp | grep vnc

Update /etc/sysconfig/iptables

Edit /etc/sysconfig/iptables file:
# vi /etc/sysconfig/iptables
Update it as follows:
# Open VNC for USER1
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5800  -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5900  -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 6000  -j ACCEPT
# Open VNC for USER2
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5801  -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5901  -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 6001  -j ACCEPT
Save and close the file. Restart iptables:
# service iptables restart

A Note About Other Linux Distributions

/etc/sysconfig/iptables works only on RHEL / CentOS / Fedora Linux. For other distros update your iptables shell script as follows:
$IPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 5801  -j ACCEPT
$IPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 5901  -j ACCEPT
$IPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 6001  -j ACCEPT
 
 
REFERENCES
http://www.cyberciti.biz/faq/linux-iptables-open-vncserver-port-6000-5800-5900/ 

UNIX Get An Alert When Disk Is Full

SkyHi @ Saturday, November 13, 2010
I want to get an alert when my disk is full under UNIX and Mac OS X? How do I set a a specified threshold and run the script via cron?

The df command report file system disk space usage including the amount of disk space available on the file system containing each file name argument. Disk space is shown in 1K blocks by default, unless the environment variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
Use df command and pass the -P option which make df output POSIX compliant (i.e. 512-byte blocks rather than the default. Note that this overrides the BLOCKSIZE specification from the environment).
# df -P /
OR
# df -P /usr
Sample Outputs:
Filesystem    512-blocks     Used     Avail Capacity  Mounted on
/dev/aacd0s1e  162491344 21988048 127503992    15%    /usr
You can now simply grep /usr file system and print out used capacity:
# df -P /usr | grep /usr | awk '{ print $5}' | sed 's/%//g'
15
Or assign value to a variable:
# output=$(df -P /usr | grep /usr | awk '{ print $5}' | sed 's/%//g')
# echo $output

Under BASH or KornShell you can use arrays indexed by a numerical expression to make code small:
# output=($(df -P /))
# echo "${output[11]}"

A Sample Shell Script

#!/bin/bash
# Tested Under FreeBSD and OS X
FS="/usr"
THRESHOLD=90
OUTPUT=($(LC_ALL=C df -P ${FS}))
CURRENT=$(echo ${OUTPUT[11]} | sed 's/%//')
[ $CURRENT -gt $THRESHOLD ] && echo "$FS file system usage $CURRENT" | mail -s "$FS file system" you@example.com
You need to modify syntax, if you are using KSH or TCSH / CSH instead of BASH. Save this script and run as a cron job:
@daily /path/to/your.df.script.sh

GUI Notification

Display warning dialog using /usr/bin/zenity
#!/bin/bash
# Tested Under FreeBSD and OS X
FS="/usr"
THRESHOLD=90
OUTPUT=($(LC_ALL=C df -P ${FS}))
CURRENT=$(echo ${OUTPUT[11]} | sed 's/%//')
[ $CURRENT -gt $THRESHOLD ] && /usr/bin/zenity  --warning  --text="The disk $FS ($CURRENT% used) is almost full. Delete some files or add a new disk." --title="df Warning"
DF GUI Warning Notification
DF GUI Warning Notification
Finally update your cronjob as follows (you need to use DISPLAY variable to display output window):
36 19 * * *  DISPLAY=:0.0 /path/to/script.sh
 
REFERENCES
http://www.cyberciti.biz/faq/mac-osx-unix-get-an-alert-when-my-disk-is-full/ 

Use awk In Bash Scripting

SkyHi @ Saturday, November 13, 2010
How do I use awk pattern scanning and processing language under bash scripts? Can you provide a few examples?

Awk is an excellent tool for building UNIX/Linux shell scripts. AWK is a programming language that is designed for processing text-based data, either in files or data streams, or using shell pipes. In other words you can combine awk with shell scripts or directly use at a shell prompt.
Print a Text File

awk '{ print }' /etc/passwd
OR
awk '{ print $0 }' /etc/passwd
Print Specific Field

Use : as the input field separator and print first field only i.e. usernames (will print the the first field. all other fields are ignored):
awk -F':' '{ print $1 }' /etc/passwd
Send output to sort command using a shell pipe:
awk -F':' '{ print $1 }' /etc/passwd | sort
Pattern Matching

You can only print line of the file if pattern matched. For e.g. display all lines from Apache log file if HTTP error code is 500 (9th field logs status error code for each http request):
awk '$9 == 500 { print $0}' /var/log/httpd/access.log
The part outside the curly braces is called the "pattern", and the part inside is the "action". The comparison operators include the ones from C:

== != < > <= >= ?:

If no pattern is given, then the action applies to all lines. If no action is given, then the entire line is printed. If "print" is used all by itself, the entire line is printed. Thus, the following are equivalent:
awk '$9 == 500 ' /var/log/httpd/access.log
awk '$9 == 500 {print} ' /var/log/httpd/access.log
awk '$9 == 500 {print $0} ' /var/log/httpd/access.log
Print Lines Containing tom, jerry AND vivek

Print pattern possibly on separate lines:
awk '/tom|jerry|vivek/' /etc/passwd
Print 1st Line From File

awk "NR==1{print;exit}" /etc/resolv.conf
awk "NR==$line{print;exit}" /etc/resolv.conf
Simply Arithmetic

You get the sum of all the numbers in a column:
awk '{total += $1} END {print total}' earnings.txt
Shell cannot calculate with floating point numbers, but awk can:
awk 'BEGIN {printf "%.3f\n", 2005.50 / 3}'
Call AWK From Shell Script

A shell script to list all IP addresses that accessing your website. This script use awk for processing log file and verification is done using shell script commands.

#!/bin/bash
d=$1
OUT=/tmp/spam.ip.$$
HTTPDLOG="/www/$d/var/log/httpd/access.log"
[ $# -eq 0 ] && { echo "Usage: $0 domain-name"; exit 999; }
if [ -f $HTTPDLOG ];
then
awk '{print}' $HTTPDLOG >$OUT
awk '{ print $1}' $OUT | sort -n | uniq -c | sort -n
else
echo "$HTTPDLOG not found. Make sure domain exists and setup correctly."
fi
/bin/rm -f $OUT

AWK and Shell Functions

Here is another example. chrootCpSupportFiles() find out the shared libraries required by each program (such as perl / php-cgi) or shared library specified on the command line and copy them to destination. This code calls awk to print selected fields from the ldd output:


chrootCpSupportFiles() {
# Set CHROOT directory name
local BASE="$1" # JAIL ROOT
local pFILE="$2" # copy bin file libs

[ ! -d $BASE ] && mkdir -p $BASE || :

FILES="$(ldd $pFILE | awk '{ print $3 }' |egrep -v ^'\(')"
for i in $FILES
do
dcc="$(dirname $i)"
[ ! -d $BASE$dcc ] && mkdir -p $BASE$dcc || :
/bin/cp $i $BASE$dcc
done

sldl="$(ldd $pFILE | grep 'ld-linux' | awk '{ print $1}')"
sldlsubdir="$(dirname $sldl)"
if [ ! -f $BASE$sldl ];
then
/bin/cp $sldl $BASE$sldlsubdir
else
:
fi
}

This function can be called as follows:
chrootCpSupportFiles /lighttpd-jail /usr/local/bin/php-cgi
AWK and Shell Pipes

List your top 10 favorite commands:
history | awk '{print $2}' | sort | uniq -c | sort -rn | head
Sample Output:

172 ls
144 cd
69 vi
62 grep
41 dsu
36 yum
29 tail
28 netstat
21 mysql
20 cat

whois cyberciti.com | awk '/Domain Expiration Date:/ { print $6"-"$5"-"$9 }'
Awk Program File

You can put all awk commands in a file and call the same from a shell script using the following syntax:
awk -f mypgoram.awk input.txt
Awk in Shell Scripts - Passing Shell Variables TO Awk

You can pass shell variables to awk using the -v option:


n1=5
n2=10
echo | awk -v x=$n1 -v y=$n2 -f program.awk

Assign the value n1 to the variable x, before execution of the program begins. Such variable values are available to the BEGIN block of an AWK program:

BEGIN{ans=x+y}
{print ans}
END{}
— To convert squid log timestamps to readable, sortable format:

gawk '{print strftime("%m/%d %H:%M:%S ",$1)" "substr($0,12,999)}' access.log > dated

— To avoid having to cut/paste the above, I have in my .profile file:

alias tim="gawk '{print strftime(\"%m/%d %H:%M:%S \",\$1)\" \"substr(\$0,12,999)}'"

— To use AWK to process comma separated data:

awk -F, '{print $1, "," $6}' excel-save.csv> extract.csv

— To count complex pattern occurrence

awk '{if (substr($2,1,4) == "2008" && $4 == "Exception") {print $1}}' test|grep -c ^

REFERENCES
http://www.cyberciti.biz/faq/bash-scripting-using-awk/

Help: Old Employees Accessing The Linux Server

SkyHi @ Saturday, November 13, 2010
I've recently noticed that two of my former employees are still accessing one of our Linux box. Old user account wasn't deleted because it has some important files. How do I make sure account get deleted without losing files and email stored in the account? Can you describe a terminations clearance policy for an employee account including email accounts, forwarding aliases, ssh / ftp, and access to vpn dialup services under Red Hat Enterprise Linux server?

Laid-off employee may seek revenge so delete and disable all unwanted account. When an employee leaves you can immediately lock down shell access by typing the following command:
# passwd -l username
The -l option disables an account by changing the password to a value which matches no possible encrypted value, and by setting the account expiry field to 1. This make sure he / she cannot get into server. You can delete a user account without removing any files as follows:
# userdel username
You can also tell userdel to remove the user's home directory and all of its contents:
# userdel -r username
Files in the user' s home directory will be removed along with the home directory itself and the user´s mail spool. Files located in other file systems will have to be searched for and deleted manually. Additional cleanup work is is left to the administrator.
Recommend Procedure To Delete User Account

The following is recommend procedure. Linux / UNIX server accounts are maintained as long as the owner is affiliated with you or your business. Generally, users or employees who leave for one reason or another will eventually lose their accounts and data. However, please consult your legal or HR department regarding local laws and privacy policy laws.
#1: Deactivate the account

First, local down user account and disable login to shell, ftp and ssh services:
passwd -l username
#2: Scan For rootkits

Scan file for virus, bad stuff and rootkits. Try chkrootkit and rkhunter software for scanning rootkits. If user accessing Linux file server via Windows or Mac operating system, use Microsoft / Mac os tools and anti-virus software to scan files. The ClamAV virus scanner is available and may be used to scan Linux / Unix file systems for viruses which infect other operating systems. Some employees leave rootkits and virus for backdoor entry. This is critical before you make a backup of existing data.
#3: Backup Data

Usually, you need to backup:

* Home directory
* Email box
* FTP directory
* Cron jobs
* Webserver files
* CVS files
* MySQL / PGSQL database etc

Just create a tarball of home directory, cron jobs, and mailbox at safe location in another directory:

# DEST=/path/to/safe/delete_accounts/user/data_$(date +"%d-%m-%Y_%H_%M_%P").tar.gz
# SHOME=/home/$user
# SMAILBOX=/usr/local/mailboxes/domain.com/$user
# SCRON=/var/spool/cron/crontabs/$user
# SFTP=/var/spool/ftp/$user
# tar -zcvf $DEST $SHOME $SMAILBOX $SCRON $SFTP

Replace $user and other paths with actual values.
#4: List Files In Other Directories

User may have left files in other directories. Type the following command to get a complete list of files owned by user vivek:
# find / -user vivek -print0 > /root/viveksfiles.txt 2>/root/error.log &
You can backup those files or simply change their ownership using find command itself. Removes all files owned by the user from /tmp, /var/tmp, and other tmp locations.
Delete User Account

Finally, you can delete the user account and all files:
# userdel -r $user
Make sure you removed the username from all groups to which it belongs in /etc/group.
#5: Removes The User's Crontab

Type the following command to backup and delete cronjobs:
# crontab -u username -l > /path/to/safe/delete_accounts/user/crontab.bak
# crontab -u username -r
#6: Removes The User's at Jobs

Type atq command to lists the user's pending jobs, unless the user is the superuser; in that case, everybody's jobs are listed. The format of the output lines:
# atq | less
# atq > /path/to/safe/delete_accounts/user/at.bak
# atrm jobid
#7: Delete All Process

You need to send a SIGKILL (-9) signal to all processes owned by the user. For example, send -KILL single to all process owned by vivek use the following commands. Get detailed inforation about running process:
# ps -fp $(pgrep -u vivek)
Get all PIDS:
# pgrep -u vivek
# pkill -9 -u vivek pid1 pid2
OR
# killall -KILL -u vivek
#8: Disable Email Login

Configure your email server to forward or deny access to email box. Usually, this is done by editing mysql or LDAP database files. Removes the incoming mail (postfix or sendmail) and POP / IMAP daemon mail files belonging to the user from /var/mail or /var/spool/mail.
Fig.01: Postfix - Disable Email Box Using Postfixadmin

Fig.01: Postfix - Disable Email Box Using Postfixadmin

You can also forward incoming email or simply delete mailbox with Postfixadmin.
#9: Disable Proxy Server and VPN Remote Login

Again update your central login database (such as LDAP) and disable all login access.
#10: Files and Emails

Generally, any files or email left on a system can be turned over to employees supervisor if necessary.
#11: Dealing With Root Level Access

If former employee had root access you may need to look out for following additional things:

1. Trojans.
2. Hidden kernel backdoor modules.
3. Rootkits.
4. Cron and at jobs can be to run arbitrary shell scripts or give back root level access again.
5. .forward file can be to run arbitrary shell scripts.
6. Unwanted and hidden network services.
7. SSH password less remote login keys etc.
8. Unwanted SUID/SGID binaries.
9. Iptables firewalls settings.
10. Removes all message queues, shared memory segments and semaphores owned by the user.

Use Identity Manager Software

Third party identity manager software can easily enable and disable access to many services. You can configure various policies based on users employment status or weekend login policy etc using an automated provisioning software.
Automation

You can write a perl or shell script to automate the entire procedure to disable access to user account and backup files / emails in other safe location.


If possible, I would also consider changing the ownerships of all the files owned by the old employee to another valid system user.

You can use find while logged in as the root user:

# find /home/fireduser -user fireduser -exec chown newuser.newgroup {} \;

REFERENCES
http://www.cyberciti.biz/faq/former-employees-keep-accessing-linux-unix-server/

Compress files using tar Command

SkyHi @ Saturday, November 13, 2010
How do I compress and backup files using tar command to another directory on same computer or another Linux computer under Ubuntu Linux?

First, open up a terminal under Ubuntu Linux. Some directories such as /etc require root permissions to read and write for backup. So you may need to run tar command using sudo command. In this example backup, /etc and your /home/vivek to /backup directory, enter:
$ sudo mkdir /backup
$ sudo tar -zcvpf /backup/files.backup.Nov_6_2009.tar.gz /etc/ /home/vivek
Where,

* z : Compress the backup file with 'gzip' to make it smaller.
* c : Create a new backup archive called /backup/files.backup.Nov_6_2009.tar.gz.
* v : Verbose mode, the tar command will display what it's doing to the screen.
* p : Preserves the permissions of the files put in the archive for restoration later.
* f /backup/files.backup.Nov_6_2009.tar.gz: Specifies where to store the backup, /backup/files.backup.Nov_6_2009.tar.gz is the filename used in this example.

How Do I Exclude Certain Files or Directories?

You can exclude all *.mp3 stored in /home/vivek/music directory with --exclude option:
$ sudo tar --exclude='/home/vivek/music/' -zcvpf /backup/files.backup.Nov_6_2009.tar.gz /etc/ /home/vivek
Another example (exclude ~/music/ and ~/Downloads/*.avi files):
$ sudo tar --exclude='/home/vivek/music/' --exclude='/home/vivek/Downloads/*.avi' -zcvpf /backup/files.backup.Nov_6_2009.tar.gz /etc/ /home/vivek
How Do I See a List Of Files Stored In Tar Ball or an Archive?

Type the following command:
$ sudo tar -ztvf /backup/files.backup.Nov_6_2009.tar.gz
Where,

* t: List the contents of an archive.

How Do I Restore Files?

You can use the command as follows to restore everything in / directory:
$ sudo tar -xvpzf /backup/files.backup.Nov_6_2009.tar.gz -C /
OR
$ cd /
$ sudo tar -xvpzf /backup/files.backup.Nov_6_2009.tar.gz
Where,

* -x: Extract the files.
* -C / : Extract the files in / directory.

In this example, you are restoring to the /delta directory.
$ sudo tar -xvpzf /backup/files.backup.Nov_6_2009.tar.gz -C /delta
How Do I Backup Files To a Remote Server Called backup.example.com?

Type the command as follows to backup /etc/ and /home/vivek directories to a remote system called backup.example.com:
$ sudo -s
# ssh user@backup.example.com "mkdir /backup"
# tar zcvpf - /etc/ /home/vivek | ssh user@backup.example.com "cat > /backup/files.backup.Nov_6_2009.tar.gz"
How Do I Restore Backup From a Remote System to Local Ubuntu Box?

Type the command
$ sudo -s
# cd /
# ssh user@backup.example.com "cat /backup/files.backup.Nov_6_2009.tar.gz" | tar zxpvf -

REFERENCES
http://www.cyberciti.biz/faq/ubuntu-howto-compress-files-using-tar/

CentOS / Redhat Iptables Firewall Configuration Tutorial

SkyHi @ Saturday, November 13, 2010
How do I configure a host-based firewall called Netfilter (iptables) under CentOS / RHEL / Fedora / Redhat Enterprise Linux?

Netfilter is a host-based firewall for Linux operating systems. It is included as part of the Linux distribution and it is activated by default. This firewall is controlled by the program called iptables. Netfilter filtering take place at the kernel level, before a program can even process the data from the network packet.

Iptables Config File

The default config files for RHEL / CentOS / Fedora Linux are:
  • /etc/sysconfig/iptables - The system scripts that activate the firewall by reading this file.

Task: Display Default Rules

Type the following command:
iptables --line-numbers -n -L
Sample outputs:
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination
1    RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination         

Chain RH-Firewall-1-INPUT (2 references)
num  target     prot opt source               destination
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
2    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 255
3    ACCEPT     udp  --  0.0.0.0/0            224.0.0.251         udp dpt:5353
4    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:53
5    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
6    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22
7    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:53
8    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited

Task: Turn On Firewall

Type the following two commands to turn on firewall:
chkconfig iptables on
service iptables start
# restart the firewall
service iptables restart
# stop the firewall
service iptables stop

Understanding Firewall

There are total 4 chains:
  1. INPUT - The default chain is used for packets addressed to the system. Use this to open or close incoming ports (such as 80,25, and 110 etc) and ip addresses / subnet (such as 202.54.1.20/29).
  2. OUTPUT - The default chain is used when packets are generating from the system. Use this open or close outgoing ports and ip addresses / subnets.
  3. FORWARD - The default chains is used when packets send through another interface. Usually used when you setup Linux as router. For example, eth0 connected to ADSL/Cable modem and eth1 is connected to local LAN. Use FORWARD chain to send and receive traffic from LAN to the Internet.
  4. RH-Firewall-1-INPUT - This is a user-defined custom chain. It is used by the INPUT, OUTPUT and FORWARD chains.

Packet Matching Rules

  1. Each packet starts at the first rule in the chain .
  2. A packet proceeds until it matches a rule.
  3. If a match found, then control will jump to the specified target (such as REJECT, ACCEPT, DROP).

Target Meanings

  1. The target ACCEPT means allow packet.
  2. The target REJECT means to drop the packet and send an error message to remote host.
  3. The target DROP means drop the packet and do not send an error message to remote host or sending host.

/etc/sysconfig/iptables

Edit /etc/sysconfig/iptables, enter:
# vi /etc/sysconfig/iptables
You will see default rules as follows:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

Drop All Traffic

Find lines:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
Update as follows to change the default policy to DROP from ACCEPT for the INPUT and FORWARD built-in chains:
:INPUT DROP [0:0]
:FORWARD DROP [0:0]

Log and Drop Spoofing Source Addresses

Append the following lines before final COMMIT line:
-A INPUT -i eth0 -s 10.0.0.0/8 -j LOG --log-prefix "IP DROP SPOOF "
-A INPUT -i eth0 -s 172.16.0.0/12 -j LOG --log-prefix "IP DROP SPOOF "
-A INPUT -i eth0 -s 192.168.0.0/16 -j LOG --log-prefix "IP DROP SPOOF "
-A INPUT -i eth0 -s 224.0.0.0/4 -j LOG --log-prefix "IP DROP MULTICAST "
-A INPUT -i eth0 -s 240.0.0.0/5 -j LOG --log-prefix "IP DROP SPOOF "
-A INPUT -i eth0 -d 127.0.0.0/8 -j LOG --log-prefix "IP DROP LOOPBACK "
-A INPUT -i eth0 -s 169.254.0.0/16  -j LOG --log-prefix "IP DROP MULTICAST "
-A INPUT -i eth0 -s 0.0.0.0/8  -j LOG --log-prefix "IP DROP "
-A INPUT -i eth0 -s  240.0.0.0/4  -j LOG --log-prefix "IP DROP "
-A INPUT -i eth0 -s  255.255.255.255/32  -j LOG --log-prefix "IP DROP  "
-A INPUT -i eth0 -s 168.254.0.0/16  -j LOG --log-prefix "IP DROP "
-A INPUT -i eth0 -s 248.0.0.0/5  -j LOG --log-prefix "IP DROP "

Log And Drop All Traffic

Find the lines:
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
Update it as follows:
-A RH-Firewall-1-INPUT -j LOG
-A RH-Firewall-1-INPUT -j DROP
COMMIT

Open Port

To open port 80 (Http server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 80 -j ACCEPT
To open port 53 (DNS Server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -m udp -p tcp --dport 53 -j ACCEPT
To open port 443 (Https server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 443 -j ACCEPT
To open port 25 (smtp server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 25 -j ACCEPT

Only allow SSH traffic From 192.168.1.0/24

-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT

Enable Printing Access For 192.168.1.0/24

-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT

Allow Legitimate NTP Clients to Access the Server

-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT

Open FTP Port 21 (FTP)

-A RH-Firewall-1-INPUT -m state --state NEW -p tcp --dport 21 -j ACCEPT
Save and close the file. Edit /etc/sysconfig/iptables-config, enter:
# vi /etc/sysconfig/iptables-config
Make sure ftp module is loaded with the space-separated list of modules:
IPTABLES_MODULES="ip_conntrack_ftp"
To restart firewall, type the following commands:
# service iptables restart
# iptables -vnL --line-numbers

Edit /etc/sysctl.conf For DoS and Syn Protection

Edit /etc/sysctl.conf to defend against certain types of attacks and append / update as follows:
 
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
net.ipv4.icmp_echo_ignore_broadcasts = 1
#net.ipv4.icmp_ignore_bogus_error_messages = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
 
See previous FAQ, "Linux Kernel /etc/sysctl.conf Security Hardening" for more details.

Alternate Configuration Option

You can skip /etc/sysconfig/iptables file and create a shell script from scratch as follows:

#!/bin/bash
# A sample firewall shell script
IPT="/sbin/iptables"
SPAMLIST="blockedip"
SPAMDROPMSG="BLOCKED IP DROP"
SYSCTL="/sbin/sysctl"
BLOCKEDIPS="/root/scripts/blocked.ips.txt"
 
# Stop certain attacks
echo "Setting sysctl IPv4 settings..."
$SYSCTL net.ipv4.ip_forward=0
$SYSCTL net.ipv4.conf.all.send_redirects=0
$SYSCTL net.ipv4.conf.default.send_redirects=0
$SYSCTL net.ipv4.conf.all.accept_source_route=0
$SYSCTL net.ipv4.conf.all.accept_redirects=0
$SYSCTL net.ipv4.conf.all.secure_redirects=0
$SYSCTL net.ipv4.conf.all.log_martians=1
$SYSCTL net.ipv4.conf.default.accept_source_route=0
$SYSCTL net.ipv4.conf.default.accept_redirects=0
$SYSCTL net.ipv4.conf.default.secure_redirects=0
$SYSCTL net.ipv4.icmp_echo_ignore_broadcasts=1
#$SYSCTL net.ipv4.icmp_ignore_bogus_error_messages=1
$SYSCTL net.ipv4.tcp_syncookies=1
$SYSCTL net.ipv4.conf.all.rp_filter=1
$SYSCTL net.ipv4.conf.default.rp_filter=1
$SYSCTL kernel.exec-shield=1
$SYSCTL kernel.randomize_va_space=1
 
echo "Starting IPv4 Firewall..."
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
 
# load modules
modprobe ip_conntrack
 
[ -f "$BLOCKEDIPS" ] && BADIPS=$(egrep -v -E "^#|^$" "${BLOCKEDIPS}")
 
# interface connected to the Internet
PUB_IF="eth0"
 
#Unlimited traffic for loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
 
# DROP all incomming traffic
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
 
if [ -f "${BLOCKEDIPS}" ];
then
# create a new iptables list
$IPT -N $SPAMLIST
 
for ipblock in $BADIPS
do
   $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG "
   $IPT -A $SPAMLIST -s $ipblock -j DROP
done
 
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST
fi
 
# Block sync
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW  -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Drop Sync"
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -j DROP
 
# Block Fragments
$IPT -A INPUT -i ${PUB_IF} -f  -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fragments Packets"
$IPT -A INPUT -i ${PUB_IF} -f -j DROP
 
# Block bad stuff
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL ALL -j DROP
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "NULL Packets"
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -j DROP # NULL packets
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "XMAS Packets"
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fin Packets Scan"
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet scans
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
 
# Allow full outgoing connection but no incomming stuff
$IPT -A INPUT -i ${PUB_IF} -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o ${PUB_IF} -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
 
# Allow ssh
$IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 22 -j ACCEPT
 
# Allow http / https (open port 80 / 443)
$IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 80 -j ACCEPT
#$IPT -A INPUT -o ${PUB_IF} -p tcp --destination-port 443 -j ACCEPT
 
# allow incomming ICMP ping pong stuff
$IPT -A INPUT -i ${PUB_IF} -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
#$IPT -A OUTPUT -o ${PUB_IF} -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
 
# Allow port 53 tcp/udp (DNS Server)
$IPT -A INPUT -i ${PUB_IF} -p udp --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
#$IPT -A OUTPUT -o ${PUB_IF} -p udp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
 
$IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 53 -m state --state NEW,ESTABLISHED,RELATED  -j ACCEPT
#$IPT -A OUTPUT -o ${PUB_IF} -p tcp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
 
# Open port 110 (pop3) / 143
$IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 110 -j ACCEPT
$IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 143 -j ACCEPT
 
##### Add your rules below ######
#
#
##### END your rules ############
 
# Do not log smb/windows sharing packets - too much logging
$IPT -A INPUT -p tcp -i ${PUB_IF} --dport 137:139 -j REJECT
$IPT -A INPUT -p udp -i ${PUB_IF} --dport 137:139 -j REJECT
 
# log everything else and drop
$IPT -A INPUT -j LOG
$IPT -A FORWARD -j LOG
$IPT -A INPUT -j DROP
 
exit 0


Recommend readings:

Mac OS X Disable Unnecessary Services

SkyHi @ Saturday, November 13, 2010
How do I disable unnecessary services under Mac OS X to secure my Mac OS X based desktop / server / laptop?

Mac OS X use the following directories to start various services (quoting from the man page):
  1. /System/Library/LaunchDaemons/ - System-wide daemons provided by Mac OS X
  2. /System/Library/LaunchAgents/ - Per-user agents provided by Mac OS X.
  3. ~/Library/LaunchAgents/ - Per-user agents provided by the user.
  4. /Library/LaunchAgents/ - Per-user agents provided by the administrator.
  5. /Library/LaunchDaemons/ - System-wide daemons provided by the administrator.
launchd manages processes, both for the system as a whole and for individual users using .plist files. Open the terminal and type the following commands to view directory files:
cd /System/Library/LaunchDaemons/
ls -l
ls -l | less
OR
cd /System/Library/LaunchAgents/
ls -l
ls -l | less

How Do I Disable Unnecessary Services?

You need to use the launchctl command as follows:
sudo launchctl unload -w /path/to/.plist/file
sudo launchctl unload -w /System/Library/LaunchDaemons/file.plist
In this example, you are disabling the Bonjour service, enter:
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponderHelper.plist

 

If you don’t fancy using the shell then there’s a GUI tool called Lingon…
http://sourceforge.net/projects/lingon/files/

 

References:

  • launchctl(1) man page.
  • http://www.cyberciti.biz/faq/disabling-unnecessary-mac-osx-services/

Linux iptables: Port Redirection Example

SkyHi @ Saturday, November 13, 2010
How do I redirect 80 port to 8123 using iptables?

You can easily redirect incoming traffic by inserting rules into PREROUTING chain of the nat table. You can set destination port using the REDIRECT target.

Syntax

The syntax is as follows to redirect tcp $srcPortNumber port to $dstPortNumber:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $srcPortNumber -j REDIRECT --to-port $dstPortNumbe
The syntax is as follows to redirect udp $srcPortNumber port to $dstPortNumber:
iptables -t nat -A PREROUTING -i eth0 -p udp --dport $srcPortNumber -j REDIRECT --to-port $dstPortNumbe
Replace eth0 with your actual interface name. The following syntax match for source and destination ips:
iptables -t nat -I PREROUTING --src $SRC_IP_MASK --dst $DST_IP -p tcp --dport $portNumber -j REDIRECT --to-ports $rediectPort

Examples:

The following example redirects TCP port 25 to port 2525:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -j REDIRECT --to-port 2525
In this example all incoming traffic on port 80 redirect to port 8123
iptables -t nat -I PREROUTING --src 0/0 --dst 192.168.1.5 -p tcp --dport 80 -j REDIRECT --to-ports 8123
Quoting from the iptables man page:
This  target is only valid in the nat table, in the PREROUTING and OUTPUT
       chains, and user-defined chains which are only  called  from  those
       chains.   It redirects the packet to the machine itself by changing the
       destination IP  to  the  primary  address  of  the  incoming  interface
       (locally-generated  packets  are  mapped to the 127.0.0.1 address).  It
       takes one option:

       --to-ports port[-port]
              This specifies a destination port or  range  of  ports  to  use:
              without  this,  the  destination port is never altered.  This is
              only valid if the rule also specifies -p tcp or -p udp.
The OUTPUT chain example:
iptables -t nat -I OUTPUT --src 0/0 --dst 192.168.1.5 -p tcp --dport 80 -j REDIRECT --to-ports 8123

How Do I View NAT Rules?

Type the following command:
iptables -t nat -L -n -v

How Do I Save NAT Redirect Rules?

Type the following command:
iptables-save

References:

Regular Expressions In grep

SkyHi @ Saturday, November 13, 2010
How do I use the Grep command with regular expressions under Linux operating systems?

Linux comes with GNU grep, which supports extended regular expressions. GNU grep is the default on all Linux systems. The grep command is used to locate information stored anywhere on your server or workstation.

Regular Expressions

Regular Expressions is nothing but a pattern to match for each input line. A pattern is a sequence of characters. Following all are examples of pattern:
^w1
w1|w2
[^ ]

grep Regular Expressions Examples

Search for 'vivek' in /etc/passswd
grep vivek /etc/passwd
Sample outputs:
vivek:x:1000:1000:Vivek Gite,,,:/home/vivek:/bin/bash
vivekgite:x:1001:1001::/home/vivekgite:/bin/sh
gitevivek:x:1002:1002::/home/gitevivek:/bin/sh
Search vivek in any case (i.e. case insensitive search)
grep -i -w vivek /etc/passwd
Search vivek or raj in any case
grep -E -i -w 'vivek|raj' /etc/passwd
The PATTERN in last example, used as an extended regular expression.

Anchors

You can use ^ and $ to force a regex to match only at the start or end of a line, respectively. The following example displays lines starting with the vivek only:
grep ^vivek /etc/passwd
Sample outputs:
vivek:x:1000:1000:Vivek Gite,,,:/home/vivek:/bin/bash
vivekgite:x:1001:1001::/home/vivekgite:/bin/sh
You can display only lines starting with the word vivek only i.e. do not display vivekgite, vivekg etc:
grep -w ^vivek /etc/passwd
Find lines ending with word foo:
grep 'foo$' filename
Match line only containing foo:
grep '^foo$' filename
You can search for blank lines with the following examples:
grep '^$' filename

Character Class

Match Vivek or vivek:
grep '[vV]ivek' filename
OR
grep '[vV][iI][Vv][Ee][kK]' filename
You can also match digits (i.e match vivek1 or Vivek2 etc):
grep -w '[vV]ivek[0-9]' filename
You can match two numeric digits (i.e. match foo11, foo12 etc):
grep 'foo[0-9][0-9]' filename
You are not limited to digits, you can match at least one letter:
grep '[A-Za-z]' filename
Display all the lines containing either a "w" or "n" character:
grep [wn] filename
Within a bracket expression, the name of a character class enclosed in "[:" and ":]" stands for the list of all characters belonging to that class. Standard character class names are:
  • [:alnum:] - Alphanumeric characters.
  • [:alpha:] - Alphabetic characters
  • [:blank:] - Blank characters: space and tab.
  • [:digit:] - Digits: '0 1 2 3 4 5 6 7 8 9'.
  • [:lower:] - Lower-case letters: 'a b c d e f g h i j k l m n o p q r s t u v w x y z'.
  • [:space:] - Space characters: tab, newline, vertical tab, form feed, carriage return, and space.
  • [:upper:] - Upper-case letters: 'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z'.
In this example match all upper case letters:
grep '[:upper:]' filename

Wildcards

You can use the "." for a single character match. In this example match all 3 character word starting with "b" and ending in "t":
grep '\<b.t\>' filename
Where,
  • \< Match the empty string at the beginning of word
  • \> Match the empty string at the end of word.
Print all lines with exactly two characters:
grep '^..$' filename
Display any lines starting with a dot and digit:
grep '^\.[0-9]' filename

Escaping the dot

The following regex to find an IP address 192.168.1.254 will not work:
grep '192.168.1.254' /etc/hosts
All three dots need to be escaped:
grep '192\.168\.1\.254' /etc/hosts
The following example will only match an IP address:
egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' filename
The following will match word Linux or UNIX in any case:
egrep -i '^(linux|unix)' filename

How Do I Search a Pattern Which Has a Leading - Symbol?

Searches for all lines matching '--test--' using -e option Without -e, grep would attempt to parse '--test--' as a list of options:
grep -e '--test--' filename

How Do I do OR with grep?

Use the following syntax:
grep 'word1|word2' filename

How Do I do AND with grep?

Use the following syntax to display all lines that contain both 'word1' and 'word2'
grep 'word1' filenae | grep 'word2'

How Do I Test Sequence?

You can test how often a character must be repeated in sequence using the following syntax:
{N}
{N,}
{min,max}
Match a character "v" two times:
egrep "v{2}" filename
The following will match both "col" and "cool":
egrep 'co{1,2}l' filename
The following will match any row of at least three letters 'c'.
egrep 'c{3,}' filename
The following example will match mobile number which is in the following format 91-1234567890 (i.e twodigit-tendigit)
grep "[[:digit:]]\{2\}[ -]\?[[:digit:]]\{10\}" filename

How Do I Hightlight with grep?

Use the following syntax:
grep --color regex filename

How Do I Show Only The Matches, Not The Lines?

Use the following syntax:
grep -o regex filename

Regular Expression Operator

Regex operator Meaning
. Matches any single character.
? The preceding item is optional and will be matched, at most, once.
* The preceding item will be matched zero or more times.
+ The preceding item will be matched one or more times.
{N} The preceding item is matched exactly N times.
{N,} The preceding item is matched N or more times.
{N,M} The preceding item is matched at least N times, but not more than M times.
- Represents the range if it's not first or last in a list or the ending point of a range in a list.
^ Matches the empty string at the beginning of a line; also represents the characters not in the range of a list.
$ Matches the empty string at the end of a line.
\b Matches the empty string at the edge of a word.
\B Matches the empty string provided it's not at the edge of a word.
\< Match the empty string at the beginning of word.
\> Match the empty string at the end of word.

grep vs egrep

egrep is the same as grep -E. It interpret PATTERN as an extended regular expression. From the grep man page:
In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{,
       \|, \(, and \).

       Traditional egrep did not support the { meta-character, and some egrep implementations support \{ instead, so portable scripts should avoid  {  in
       grep -E patterns and should use [{] to match a literal {.

       GNU grep -E attempts to support traditional usage by assuming that { is not special if it would be the start of an invalid interval specification.
       For example, the command grep -E '{1' searches for the two-character string {1 instead of reporting a syntax  error  in  the  regular  expression.
       POSIX.2 allows this behavior as an extension, but portable scripts should avoid it.

References:

  • man page grep and regex(7)
  • info page grep
REFERENCES
http://www.cyberciti.biz/faq/grep-regular-expressions/

CentOS / Redhat: Create Software RAID 1 Array

SkyHi @ Saturday, November 13, 2010
Recently, I've added another 73GB SAS disk to my Linux server after the installation. I've 30GB empty partition on old hard disk. How do I convert old /dev/sda3 and new /dev/sdb1 (both 30GB) into RAID 1 to improve NFS server speed and reliability?

RAID devices are virtual devices created from two or more real block devices. Linux supports RAID1 and other levels. You need to have same size partition on both disks i.e. on second disk create partitions exactly the same size as those on the first disk, and set the type as fd (Linux raid autodetect). You need to use the following commands to create RAID 1.
WARNING! These examples may crash your computer or may result into data loss if not executed properly. These examples involves disk partition manipulation using the fdisk command and building (formatting) file systems using the mkfs.ext3 command. So make sure you backup all data before typing any one of the following command.
Our sample RAID -1 setup with two partitions:
+------------+
|            |
| /dev/sda3  | ===============+
|            |                |
+------------+                |
  37GB                        | =======> RAID-1 /dev/md0
                              |
+------------+                |
|            |                |
| /dev/sdb1  | ===============+
|            |
+------------+
  37GB

Step # 1: List Partitions

Type the following commands:
# fdisk -l
# fdisk -l /dev/sda

Sample outputs:
Disk /dev/sda: 73.2 GB, 73295462400 bytes
255 heads, 63 sectors/track, 8910 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        3929    31455270   83  Linux
/dev/sda3            3930        8779    38957625   83  Linux
/dev/sda4            8780        8910     1052257+   5  Extended
/dev/sda5            8780        8910     1052226   82  Linux swap / Solaris
For example, purpose you will use /dev/sda3 (size 37G). Now, list second disk partitions, enter:
# fdisk -l /dev/sdb
Sample outputs:
Disk /dev/sdb: 73.2 GB, 73295462400 bytes
255 heads, 63 sectors/track, 8910 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

Step # 2: Create 37G Partitions For /dev/sdb

Type the following command:
# fdisk /dev/sdb
Sample outputs:
The number of cylinders for this disk is set to 8910.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): 
To add a new partition, type n command followed by p command as follows:
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-8910, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-8910, default 8910): +37G
To print the partition table type p command, enter:
Command (m for help): p

Disk /dev/sdb: 73.2 GB, 73295462400 bytes
255 heads, 63 sectors/track, 8910 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1          37      297171   83  Linux
Finally, set partition type to "Software Raid" i.e. type 0xfd *(type t command followed by fd code to change partition type to Software RAID):
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): fd

Command (m for help): p

Disk /dev/sdb: 73.2 GB, 73295462400 bytes
255 heads, 63 sectors/track, 8910 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1          37      297171   fd  Linux raid autodetect
Save the changes and exit to shell prompt by typing w command:
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Step # 3: Create / Update 37G Partitions For /dev/sda

You need to delete /dev/sda3 (make sure you backup all data) and/or set it to software raid as follows using the fdisk command:
# fdisk /dev/sda
Sample outputs:
The number of cylinders for this disk is set to 8910.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/sda: 73.2 GB, 73295462400 bytes
255 heads, 63 sectors/track, 8910 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        3929    31455270   83  Linux
/dev/sda3            3930        8779    38957625   83  Linux
/dev/sda4            8780        8910     1052257+   5  Extended
/dev/sda5            8780        8910     1052226   82  Linux swap / Solaris

Command (m for help): t
Partition number (1-5): 3
Hex code (type L to list codes): fd
Changed system type of partition 3 to fd (Linux raid autodetect)

Command (m for help): p

Disk /dev/sda: 73.2 GB, 73295462400 bytes
255 heads, 63 sectors/track, 8910 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        3929    31455270   83  Linux
/dev/sda3            3930        8779    38957625   fd  Linux raid autodetect
/dev/sda4            8780        8910     1052257+   5  Extended
/dev/sda5            8780        8910     1052226   82  Linux swap / Solaris

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.

Reload Partition Table Changes

Use the partprobe command to reload the changes without rebooting the box:
# partprobe /dev/sda
OR
# echo 1 > /sys/block/sdb/device/rescan

Step #3: Create RAID 1 Array

To create RAID1 using /dev/sda3 and /dev/sdb1, enter:
# mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda3 /dev/sdb1
To see RAID build progress, enter:
# watch cat /proc/mdstat
Sample outputs:

Fig.01: RAID 1 mirroring
Fig.01: RAID 1 mirroring

Once build completed create a filesystem on the new software raid devices, enter:
# mkfs.ext3 /dev/md0
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
4872896 inodes, 9737360 blocks
486868 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
298 block groups
32768 blocks per group, 32768 fragments per group
16352 inodes per group
Superblock backups stored on blocks:
 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
 4096000, 7962624

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 39 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Mount RAID1 at /raid1

Type the following commands:
# mkdir /raid1
# mount /dev/md0 /raid1/
# df -H /raid1/

Sample outputs:
Filesystem             Size   Used  Avail Use% Mounted on
/dev/md0                40G   185M    38G   1% /raid1

How Do I Test My RAID 1 Array Speed?

Simply use the dd command as follows:
# cd /raid1/
# dd if=/dev/zero of=output bs=8k count=256k
# rm output

262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 6.01068 seconds, 357 MB/s

Update /etc/fstab

Make sure RAID1 get mounted when you reboot the system (note >> append redirection):
# echo '/dev/md0 /raid1 ext3 noatime,rw 0 0' >> /etc/fstab

How Do I Get Detailed Information About RAID 1?

Type the following command:
# mdadm --query --detail /dev/md0
Sample outputs:
/dev/md0:
        Version : 0.90
  Creation Time : Wed May 26 01:58:53 2010
     Raid Level : raid1
     Array Size : 38949440 (37.15 GiB 39.88 GB)
  Used Dev Size : 38949440 (37.15 GiB 39.88 GB)
   Raid Devices : 2
  Total Devices : 2
Preferred Minor : 0
    Persistence : Superblock is persistent

    Update Time : Wed May 26 02:18:22 2010
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           UUID : b6f207e4:7f73484f:53f64bfd:e70b77d8
         Events : 0.2

    Number   Major   Minor   RaidDevice State
       0       8        3        0      active sync   /dev/sda3
       1       8       17        1      active sync   /dev/sdb1
REFERENCES
http://www.cyberciti.biz/faq/centos-redhat-rhel-linux-setup-create-raid1/