Administration

Linux Server Optimization Guide

This is a small guide on how to optimizing a linux server for performance, so that you can extract the full juice of your server. A lot of times, the default configurations are bad, and work slow- especially they matter a lot when you have low ram.

How to configure SSHD on Xinetd

This is small tutorial on how to configure OpenSSH daemon on Xinetd.

This is useful if your users don't login too frequently over SSH, hence it wastes memory and CPU just by running in the background.

Note that SSHD needs to generate the server key before it reponds which can take long time depending on your key size. For small keysizes, it works well.

To change the port, you need to edit /etc/services. I will not be covering that here as that job is too easy to do (you can always request a tutorial if you want).

libphp5.so on Apache 2 is faster than CGI or FastCGI

Why this site loads so fast ? The reason is we are using Apache 2.2.10 with libphp5.so

Earlier we were using CGI.

I also tried PHP-FastCGI

Setting up User, Group Filesystem Quotas on Linux

This simple tutorial explains the process of setting up User and Group quotas on Linux (tested on Fedora 9. steps may be similar for any UNIX OS).

As you know UNIX and its brother Linux is a multiple user Operating System. So, we need to check that no user abuses the system by storing large files which leads to lack of Hard Disk space. So, we have Quotas on Linux. Quotas are nothing but assigning a specific amount of Hard Disk Space to a user or a group. Linux supports limiting space as well as no. of files. While commonly used is Limiting Space, in some cases you may need limiting no. of files also. Limiting Space & No. of Files can go hand in had or they can be assigned separately i.e. both of them are independent. You can have limiting no. of files which implies that the user can have only a specified no. of files while their sizes don't matter.

So, let's come to the actual part of the tutorial.

By default in any UNIX system, users' files are stored in /home/

Here in this tutorial, we assume that you don't have a separate partition for /home, so users' files are contained the root partition under sub-directory /home. If you have such a partition just, replace things with /home where filesystem is referred to.

User Quotas

User Quotas means limiting space (or no. of files) for a user which is applicable only the user.

Step 1: Remount / with usrquota option --

# mount -v -o remount,usrquota /

This will remount your / partition with usrquota option which stands for "Enable User Quotas"

Step 2: Run quotacheck --

# quotacheck -ucvm /

Here, -ucvm has four options -

u = check user quota files
c = create quota files
v = verbose
m = don't remount the file-system to read-only

m is required because we're checking / and / cannot be mounted read-only anytime.

Step 3: Turn Quotas On --

# quotaon -vu /

Again in the options -vu; u stands for enable user quotas and v stands for verbose. Further we're not going to explain what is u and what is v.

Step 4: Set Quota for a user --

# setquota -u user_name 1024 1024 20 22

In the above command, first number 1024 stands for block-soft-limit

Block Soft Limit means this is the size in KB when a user will be warned about his disk usage nearing to quota limit, but he can still store files unless he reaches block hard-limit where he won't be allowed to write to the HDD until he frees some space.

The second number is Block-Hard Limit.

The third number is Inode soft limit. As said above we can limit the number of files, Soft Limit means he will be warned when he reaches this many number of files and won't be allowed to write when he reaches Inode Hard Limit which is the last field in the command.

To check that quotas have been implemented correctly (Disk Space):


# su -l user
$ dd if=/dev/zero bs=1k count=2048 of=bigfile

When you execute above commands then you will find a file of only 1024 KB as we set the quota of 1024 KB for user. Further if you try to add more files you will get error message.

To check no. of file type quotas:


# su -l user
$ COUNT=1; while [ $COUNT -lt 25 ]; do touch file$COUNT; let COUNT=$COUNT+1; done

Here, we have set a count of 24 files to be created. COUNT=1 sets a shell variable COUNT with value 1.

Then we use while loop to create fileN where N is replaced by the current number in COUNT which is then incremented by one after creation of fileN until COUNT variable reaches 24. Here you will receive warning message when you have created 20 files and get error when you try to create then 23rd file.

so, we have done with user quotas.

The process of setting up group quotas is very much similar except that you need to use grpquota instead of usrquota while remounting ; -g option for quotacheck and quotaon.

Then while assigning quotas to groups you need to give -g instead of -u.

All other syntax is same.

To make quotas permanent, you need to edit /etc/fstab.

Find your file system in /etc/fstab.

To find / partition in fstab, see the second field of fstab.

Some line will have ONLY and ONLY a / in the second field. This is the partition whose options in fstab need to be modified.

In my system, I have two hard disks, so I use LVM to merge them. So don't be astonished by the friendly device name.

My fstab entry is like this -

/dev/system/root        /                       ext3    defaults       1 1

To enable user & group quotas permanently, this line should be changed so that it looks like this -

/dev/system/root        /                       ext3    defaults,usrquota,grpquota        1 1

That's all!

Have a nice day. Comment if you get stuck somewhere or have suggestions.

Nilesh
iTech7 Site and Server Administrator

Creating an automatic installer for HTTPD

This tutorial explains how to create a simple shell script with default HTTPD compile options which can install HTTPD just in one command PROVIDED you have sudo and the NOPASSWD: ALL in your username's entry in the sudoers file.

So, here's a script which can do the above task. Please note that you need not rewrite all the options given to configure while compiling first time, you can just take a copy of config.nice script which is created by configure present in the build directory. For instance, if your apache directory is /usr/local/apache2 ; then you'll find config.nice in /usr/local/apache2/build.

Actually I must say this is an extension of the config.nice file as I myself created this using config.nice Wink

Note: I have used config,nice from httpd-2.2.9's compilation, may not work for httpd-1.x or httpd-2.0.x

#!/bin/bash

# Apache Install Script
# Modified version of config.nice

# ------- PARAMETERS REQUIRED -------
# 1st Parameter - Extracted Source code directory

if [ ! $1 ]; then

echo -e "You must pass the first argument as the SOURCE CODE directory\n"

exit 1

fi

SRCDIR=$1

if [ -d $SRCDIR ] && [ $(pwd) != $SRCDIR ]; then

echo -e "Current Working Directory is $(pwd)\n\n"

echo -e "Changing Directory to $SRCDIR\n\n"

cd $SRCDIR &> /dev/null

CD_RETVAL=$?

if [ $CD_RETVAL -ne 0 ]; then

echo -e "Failed to change directory to $SRCDIR\n\n"

exit $CD_RETVAL

fi

fi

# Replacing ./configure from config.nice to $SRCDIR/configure as the configure script is in $SRCDIR
# Parameters for configure taken from config.nice

# configure by default will install in /usr/local/apache2

"$SRCDIR/configure" \
"-C" \
"--build=i686-pc-linux-gnu" \
"--host=i686-pc-linux-gnu" \
"--target=i686-pc-linux-gnu" \
"--enable-mods-shared=authn-file authn-dbm authn-dbd authn-default authn-anon authn-alias authz-host authz-groupfile authz-user authz-dbm authz-owner authz-default auth-basic auth-digest file-cache cache disk-cache mem-cache dbd ext-filter include filter substitute charset-lite deflate log-config log-forensic logio env mime-magic cern-meta expires headers ident usertrack unique-id setenvif version proxy proxy-connect proxy-ftp proxy-http proxy-ajp proxy-balancer ssl mime dav status autoindex asis info cgid cgi suexec dav-fs dav-lock vhost-alias negotiation dir imagemap actions speling userdir rewrite alias" \
"--enable-modules=so" \
"--with-mpm=worker" \
"--with-included-apr" \
"$@"

AUTOCONF_RETVAL=$?

if [ $AUTOCONF_RETVAL -ne 0 ]; then

echo -e "\n\nError\n\n"

exit $AUTOCONF_RETVAL

fi

make -f Makefile

sudo make -f Makefile install

This script will install httpd in /usr/local/apache2

Enjoy! Smile

Bugs, if found, shall be posted in comments and the same for any suggested improvements or modifications Wink

Using a file as a swap instead of a whole partition

Newer version of Linuxes have the ability to use a single file as a swapfile like windows does (pagefile).

Some simple steps to do this ->

Assuming that you don't have swap partition ->

# dd if=/dev/zero of=/swapfile bs=1<bytes|KB|MB|GB> This should be 1 unit; so that it makes easy to specify no.. in count argument count=<size> This controls the size actually. Assuming that you set bs=1MB ; count=100 will create a dummy file of 100MB
# chmod 600 /swapfile
# mkswap /swapfile
# swapon /swapfile

To make use of this swap file by default when you boot Linux, add this line to /etc/fstab -

/swapfile       swap         defaults      0  0

In this way, you can have multiple swap files of custom sizes

Extracting Data from a file using cut and grep

Ever thought of having a database as a single TEXT file ? You could do that, but how do you extract data from it ?

This tutorial deals with extracting data from a SINGLE file very much similar to a RDBMS SELECT with WHERE query.

Let's create a file with the following lines -

A;A1;A2;A3;A4;A5
B;B1;B2;B3;B4;B5
C;C1;C2;C3;C4;C5
D;D1;D2;D3;D4;D5
E;E1;E2;E3;E4;E5
F;F1;F2;F3;F4;F5

As you see above, data has been separated by semicolons (Wink.

Suppose you want to extract the 4th field from the file for the record which starts with C.

To do the above, use this -

$ grep ^C file | cut -f4 -d\;

Please note that this will give you the value which says C3. This is because the first entry itself is a field.

In the above command, grep ^C means show all lines starting with the letter C.

And the next part cut -f4 -d\; means ONLY show the fourth field and since we have separated our fields by a semicolon, the -d\; option is used. Here you need to put the backslash before the semicolon because semicolon is a SHELL character. You could also use colon (Smile in the file and the cut command to avoid this problem.

Please comment if you have questions/suggestions.

Recovering Lost Root password on Linux

Many people when forget their root password simply format and reinstall the system. No you don't need to do that!

This tutorial makes use of GRUB kernel parameters. In most cases GRUB is the boot loader. If you use a different boot loader then you will need to figure out how to alter boot kernel parameters "TEMPORARILY FOR THIS SESSION".


Values to be entered are given in quotes. You must enter the value WITHOUT quotes.

By default GRUB is setup to boot with hiddenmenu that is the OS menu will not be available and the default OS is booted in 5 or 10 seconds unless you interrupt it using some key.

When grub appears -

If the menu is hidden interrupt it by pressing arrow keys and then press 'e' by selecting the Linux installation for which you want to recover the root password.

This will show you three lines which look like this -

root (hd0,0)
kernel /vmlinuz-2.6.25.3-18.fc9.i686 ro root=/dev/sda1 quiet
initrd /initrd-2.6.25.3-18.fc9.i686.img

with the first line selected.

using arrow keys move the second line (or the line which starts with 'kernel') and press 'e'

This will allow you to edit the line.

Press the "End" key on your keyboard so that the cursor moves to the end.

Once it moves to the end, leaving a space just enter '1'.

Then press "Enter" and then 'b'.

Now the kernel will tell init to go to run-level 1 which is Single user mode with root logged in automatically.

You will get a Bourne Shell (SH) Prompt which looks something like this -

sh-3.2#

Type 'passwd' without any arguments.

It will demand new password. Type it (it won't be echoed on the screen). Press enter. It will ask to confirm the password. Re-enter the password and press enter.

YOU ARE DONE!

Now restart your PC by either typing 'reboot' on the shell or by pressing Ctrl+Alt+Del

sh-3.2# passwd
New UNIX password: 
Retype new UNIX password: 
passwd: all authentication tokens updated successfully.
sh-3.2# reboot

Now boot normally and you should be able to login as root.

Watching a command's output

Suppose you have a command for which you wish to monitor on LIVE. of course you can use Log Files and and use tail -f to the log files.

There is another method.

Consider the command mailq.

mailq shows you the messages presently in queue for sending by your MTA (sendmail, postfix, exim).

watch is command used to monitor this in REALTIME

it has a option -n which specifies the interval to re run the command in.

Consider this - Running mailq every 5 seconds.

# watch -n 5 'mailq'

watch will open a full screen window in which the command output will be shown at specified interval.

Check out its man page for more info.

Pingstat!

What is Pingstat ?

Pingstat is small Linux Bash Script which can log the results of PINGING a particular IP in a LOGFILE if specified OR output to STDOUT in a user-friendly format -

[time] PING [IP-ADDR] SUCCESS/FAILURE

 

LOGFILE by default is $HOME/pingstat.log

The script has a inbuilt default IP variable called $DEFAULTIP which is pinged if no IP is given as the first command line argument..

The script takes another argument which can have values of 1, YES, Yes, Y, TRUE, True  and when any of the values are found it will remove $LOGFILE if it exists.

It has two internal variables called $PINGCOUNT and $TIMEOUT (Their names say what they mean).

It has one more variable called $PINGCMD i.e. the name (or path) of the UNIX `ping` command ... in most cases its gonna be `ping`

So here's the script-

Feedback and Suggestions would be appreciated

#!/bin/bash

#PING AND LOG STATUS

#First argument which can be passed is the IP-Address
#If IP Address is not specified on the command line arguments,
#Then $DEFAULTIP will be used as declared below

#Second argument which can be specified is to remove the old log file
#Second argument can have values of - 1, TRUE, Yes, YES, True

#If second argument is not given then result is appended to ..
#existing logfile

#SOME DEFAULT SETTINGS .... CHANGE AS YOU WISH                

#The default IP to PING if no IP was given as the first argument

DEFAULTIP='121.246.205.1' 

#The PING command: Usually `ping`

PINGCMD='ping' 

#Number of packaets to send.... 
#Keep this small < 5 if you are pinging frequestly using Cron job to avoid 
#conflicts with the next ping

PINGCOUNT=2 

#Timeout in seconds if no response is recieved.....

#Keep this small < 5 if you are pinging frequently using Cron job to avoid
#conflicts with the next ping

TIMEOUT=5

#The LOG File PATH to save the result -

#Format of the LOG File will be Like this - 
#[time] PING $IP SUCCESS/FALIURER
#If LOGFILE is not specified, then output will be STDOUT

LOGFILE=$HOME/pingstat.log

#END CONFIGURATION SECTION

rmf()

{

        rm -f $LOGFILE

}


if [ $1 ]; then

        IP=$1

        else

                if [ ! $DEFAULTIP ]; then 

                echo -e "\nNO IP ADDRESS DEFINED\n"; 

                exit 1;

                else

                IP=$DEFAULTIP

                fi

fi

REMOLDLOG=$2

if [ -f $LOGFILE ]; then

        case "$REMOLDLOG" in

                        1)
                                rmf
                                ;;
                        TRUE)
                                rmf
                                ;;
                        YES)
                                rmf
                                ;;
                        Yes)
                                rmf
                                ;;
                        Y)
                                rmf
                                ;;
                        True)
                                rmf
                                ;;
        esac

fi

if [ ! $TIMEOUT ]; then

TIMEOUT=5

fi

if [ ! $PINGCOUNT ]; then

PINGCOUNT=2

fi

if [ ! $PINGCMD ]; then

PINGCMD='ping'

fi

if [ ! $LOGFILE ]; then

LOGFILE="/dev/stdout"

fi

$PINGCMD -c$PINGCOUNT -W$TIMEOUT $IP &> /dev/null

if [ $? -eq 0 ]; then

        echo -e "[$(date)] - PING $IP SUCCESS \n" >> $LOGFILE

else

        echo -e "[$(date)] - PING $IP FAILURE \n" >> $LOGFILE

fi

 

Syndicate content