Sunday, 19 May 2013

Apache MaxClients Calculation

MaxClients:

The MaxClients directive sets the limit on the number of simultaneous requests that will be served. Any connection attempts over the MaxClients limit will normally be queued, up to a number based on the ListenBacklog directive. Once a child process is freed at the end of a different request, the connection will then be serviced.

For non-threaded servers (i.e., prefork), MaxClients translates into the maximum number of child processes that will be launched to serve requests. The default value is 256; to increase it, you must also raise ServerLimit.

calculating MaxClients value:

#!/bin/bash
tome=$(free -m | grep -i mem | awk '{print $2}')
htps=$(ps -aylC httpd |grep "httpd" |awk '{print $8'} |sort -n |tail -n 1)
mysme=$(ps aux | grep 'mysql' | awk '{print $6}' |sort -n |tail -n 1)
rafa=1024
nmysme=$(expr $mysme / $rafa)
nhtps=$(expr $htps / $rafa)
echo -e "\nTotal Memory = $tome"
echo -e "Largest httpd Process = $nhtps"
echo -e "Mysql Memory = $nmysme"
maxc=`expr $tome - $nmysme`
maxcl=`expr $maxc / $nhtps`
echo -e "\nSo, The MaxClients = $maxcl"
echo -e "(we can use nearest round of value from $maxcl)"


For example, copy the above code in a file named "maxcalc.sh" then

# chmod 755 maxcalc.sh
# ./maxcalc.sh


The output will belike,
Total Memory = 15905
Largest httpd Process = 16
Mysql Memory = 1934

So, The MaxClients = 873

(we can use nearest round of value from 873)


cheers !!!

Friday, 17 May 2013

Apache: Prefork MPM vs Worker MPM

Difference between Prefork and Worker MPM modules.

prefork

worker

(mpm_winnt This Multi-Processing Module is optimized for Windows NT.)

(mpm_netware Multi-Processing Module implementing an exclusively threaded web server optimized for Novell NetWare)

Prefork MPM:

A prefork mpm handles requests just like apche 1.3. As the name suggests this will pre fork necessary child process while starting apache. It is suitable for websites which avoids threading for compatibility for non-thread-safe libraries . It is also known as the best mpm for isolating each request.

Working:

A single control process is responsible for launching child processes which listen for connections and serve them when they arrive. Apache always tries to maintain several spare or idle server processes, which stand ready to serve incoming requests. In this way, clients do not need to wait for a new child processes to be forked before their requests can be served. We can adjust this spare process through the apche conf. For a normal server which is having 256 simultaneous connections can use the default prefork settings.

Perfork is the default module given by apache.

# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild directive sets the limit on the number of requests that an individual child server process will handle. After MaxRequestsPerChild requests, the child process will die. If MaxRequestsPerChild is 0, then the process will never expire

Worker MPM:

A worker mpm is an Multi-Processing Module (MPM) which implements a hybrid multi-process multi-threaded server. By using threads to serve requests, it is able to serve a large number of requests with fewer system resources than a process-based server.

The most important directives used to control this MPM are ThreadsPerChild, which controls the number of threads deployed by each child process and MaxClients, which controls the maximum total number of threads that may be launched.

Strength : Memory usage and performanance wise its better than prefork

Weakness : worker will not work properly with languages like php

Working:

A single control process (the parent) is responsible for launching child processes. Each child process creates a fixed number of server threads as specified in the ThreadsPerChild directive, as well as a listener thread which listens for connections and passes them to a server thread for processing when they arrive.

Apache always tries to maintain a group of spare or idle server threads, which stand ready to serve incoming requests. In this way, clients do not need to wait for a new threads or processes to be created before their requests can be served. The number of processes that will initially launched is set by the StartServers directive. During operation, Apache assesses the total number of idle threads in all processes, and forks or kills processes to keep this number within the boundaries specified by MinSpareThreads and MaxSpareThreads. Since this process is very self-regulating, it is rarely necessary to modify these directives from their default values. The maximum number of clients that may be served simultaneously (i.e., the maximum total number of threads in all processes) is determined by the MaxClients directive. The maximum number of active child processes is determined by the MaxClients directive divided by the ThreadsPerChild directive

Event MPM(This MPM is experimental, so it may or may not work as expected):

The event Multi-Processing Module (MPM) is designed to allow more requests to be served simultaneously by passing off some processing work to supporting threads, freeing up the main threads to work on new requests. It is based on the worker MPM, which implements a hybrid multi-process multi-threaded server. Run-time configuration directives are identical to those provided by worker.

To use the event MPM, add --with-mpm=event to the configure script's arguments when building the httpd.

Worker MPM:
StartServers 35
MaxClients 256
MinSpareThreads 30
MaxSpareThreads 305
ThreadsPerChild 255
MaxRequestsPerChild 0

Prefork MPM:

StartServers 20
MinSpareServers 50
MaxSpareServers 100
MaxClients 200
MaxRequestsPerChild 20000

Thursday, 16 May 2013

MySQL storage on RamFS or TmpFS partition

Mount tmpfs to a folder:

# mkdir /var/ramfs

# mount -t ramfs -o size=1G ramfs /var/ramfs/


Here we mounted ramfs to /var/ramfs. I am using ramfs in oppose to tmpfs mainly because:

    ramfs grows dynamically(tmpfs doens’t)

    ramfs doesn’t use swap(while tmpfs does)


RAM-backed file system is mounted, so now I need to populate it with MySQL files for processing.
To do that I will need to stop mysql, copy it’s database files over to ramfs, adjust AppArmor and MySQL settings and start mysql server again. Here is the chain of commands to do that:

Copying files:

# /etc/init.d/mysql stop

# cp -R /var/lib/mysql /var/ramfs/

# chown -R mysql:mysql /var/ramfs/mysql


Tweaking MySQL config:

# cp /etc/mysql/my.cnf /etc/mysql/original-my.cnf

# vi /etc/mysql/my.cnf


Find line with ‘datadir‘ definition(it will look something like datadir = /var/lib/mysql) and change it to

datadir = /var/ramfs/mysql

Looks like we’re done with settings, let’s see if it will work:

# /etc/init.d/mysql start

If mysql daemon starts(double check /var/log/mysql.err for any errors) and you can connect to it, mostlikely now we’re running fully off of a RAM device. To double check it, run this from mysql client:

mysql> show variables where Variable_name = 'datadir' \G
*************************** 1. row ***************************
Variable_name: datadir
Value: /var/ramfs/mysql/
1 row in set (0.00 sec)


The real reason you don't see anyone wanting to run MyISAM from a tmpfs is because MySQL has the EMORY engine for that purpose.  If you want to keep a database in memory, that's the correct way to do it.  Someone actually wanting to do a memory database would start with converting the handful of TEXT and BLOB fields in the schema over to VARCHARs, since the MEMORY engine doesn't support either.

Disadvantages of Ramfs and Tmpfs:

Since both ramfs and tmpfs is writing to the system RAM, it would get deleted once the system gets rebooted, or crashed. So, you should write a process to pick up the data from ramfs/tmpfs to disk in periodic intervals. You can also write a process to write down the data from ramfs/tmpfs to disk while the system is shutting down. But, this will not help you in the time of system crash.

Tuesday, 7 May 2013

Protecting Web Servers from Distributed Denial of Service Attacks(DDoS):

Possible SYN flooding on port 80. Sending cookies:

If frequently faced an outage of web services. On investigating, I found that it had something creeping up in it's logs. Something which read -

    kernel: possible SYN flooding on port 80. Sending cookies.

It looked like a Denial of service attack. It was evident that I needed to beef up security!

Avoiding a DDOS attack on a web server:

iptables comes with a module (limit) using which a DDOS attack can be tackled. Depending on the type of web service running on the server, I decided a limit of 15 HTTP syn packets per second would be enough.

First, We had a look at the existing rules

    # iptables -L -v

This shows you the rules and the default policy that are set in the existing chains - INPUT, FORWARD and OUTPUT.

Then we followed these quick steps -

1. Create a new chain and name it, say, DDOS_SYNFLOOD,

    # iptables -N DDOS_SYNFLOOD


2. Add a limit to no.of packets 15 per second with a max burst of about 20, by using the limit module.

    # iptables -A DDOS_SYNFLOOD -m limit --limit 15/second --limit-burst 20 -j ACCEPT

Note: Other units - /minute ,  /hour , and /day

3. And of course, we will need to drop packets which exceed the above limitation

    # iptables -A DDOS_SYNFLOOD -j DROP

4. Now all that was left was to "jump" to this new chain for incoming tcp syn packets on port 80.

    # iptables -A INPUT -p tcp --syn --dport http -j DDOS_SYNFLOOD

And to look at what was set up -

    # iptables -L -v

    Chain INPUT (policy ACCEPT 95 packets, 4988 bytes)
     pkts bytes target     prot opt in     out     source               destination
        0     0 DDOS_SYNFLOOD  tcp  --  any    any     anywhere             anywhere            tcp dpt:http flags:FIN,SYN,RST,ACK/SYN

    ......
    ......
    ......
    ......

    Chain DDOS_SYNFLOOD (1 references)
     pkts bytes target     prot opt in     out     source               destination
        0     0 ACCEPT     all  --  any    any     anywhere             anywhere            limit: avg 15/sec burst 20
        0     0 DROP       all  --  any    any     anywhere             anywhere

And since then, We have had a few peaceful nights.

We should remember, iptables works sequentially and jumps to the target of the first match. Hence, you will need to ensure that there are no conflicting rules ahead of this one to avoid an undesired result.

I also added,

# echo 1 > /proc/sys/net/ipv4/tcp_syncookies

More info on limit module:

   limit
       This  module  matches at a limited rate using a token bucket filter.  A
       rule using this extension  will  match  until  this  limit  is  reached
       (unless  the `!' flag is used).  It can be used in combination with the
       LOG target to give limited logging, for example.

       [!] --limit rate[/second|/minute|/hour|/day]
              Maximum average matching rate: specified as a  number,  with  an
              optional  `/second',  `/minute',  `/hour', or `/day' suffix; the
              default is 3/hour.

       --limit-burst number
              Maximum initial number of packets to  match:  this  number  gets
              recharged  by  one  every  time the limit specified above is not
              reached, up to this number; the default is 5.

Relish !!!

Thursday, 2 May 2013

Recalling command history - Bash Shell

 Recalling command history:

!! - Last command and all arguments

!-3 - Third-to-last command and all arguments

!^ - First argument of last command

!:3 - Third argument of last command

!$ - Last argument of last command

!* - All arguments of the last command

!30 - Expands to the 30th command in history

!find - Last command beginning with 'find'

!?find - Last command containing 'find'

^name^type - Last command with first instance of 'name' replaced with 'type

!:gs/name/type - Last command with all instances of 'name' replaced with 'type'

<command>:p - Don't execute and print command.


Command to trim the Whitespace:

echo -e "Here is the command to trim \n \n White space" | /usr/bin/tr -d '[:space:]'