Implement bonding in RHEL 5

Bonding is the process of combining 2 NICs on a system into a single device. For e.g., if you have 2 network cards on a machine, eth0 and eth1, you combine the same into a bond device, bond0 and then configure an IP for this bond device.

Why do we have to do that, you may ask. In the case that I mentioned, if I configure bond0 as 192.168.1.5, both eth0 and eth1 can send or receive packets that are meant for bond device IP(192.168.1.5). Its like you now have 2 paths to reach a destination. Bond devices can be configured in different modes which can be utilized to provide fault tolerance, greater performance or both, depending on the mode.

Bonding is talked about in greater detail in  /usr/share/doc/kernel-doc-<kernel version>/Documentation/networking/bonding.txt.

As usual, all my experiments are on either Xen or VMWare guests and this one is no different. The below steps successfully worked for me on a RHEL 5.3 Xen guest. To start with, eth0 was configured as 192.168.122.118 while eth1 remained unassigned. I am about to create a bond device bond0 with eth0 and eth1, and assign this IP into it.

1. Add the below lines to /etc/modprobe.conf

alias bond0 bonding
options bond0 mode=1 miimon=100

We are loading the bonding kernel module required to make this work, along with some options. mode=1 means that I have opted for active-backup setup. Here, only one slave in the bond device will be active at the moment. If the active slave goes down, the other slave becomes active and all traffic is then done via the newly active slave. If this sounds a bit confusing, just read on. Also, the value of miimon specifies how often MII link monitoring occurs. For a complete list of all the available arguments, feel free to check the kernel documentation.

2. Create bond0 device file, /etc/sysconfig/network-scripts/ifcfg-bond0 with the following content:

DEVICE=bond0
BOOTPROTO=none
ONBOOT=yes
NETWORK=192.168.122.0
NETMASK=255.255.255.0
IPADDR=192.168.122.118
USERCTL=no

The lines are self-explanatory, defining the device name and then specifying its IP address, netmask and all.

3. Create /etc/sysconfig/network-scripts/ifcfg-eth0 with content:

DEVICE=eth0
MASTER=bond0
SLAVE=yes
USERCTL=no
BOOTPROTO=dhcp
IPV6INIT=yes
IPV6_AUTOCONF=yes
ONBOOT=yes

4. Create /etc/sysconfig/network-scripts/ifcfg-eth1 with content:

DEVICE=eth1
MASTER=bond0
SLAVE=yes
USERCTL=no
BOOTPROTO=dhcp
IPV6INIT=yes
IPV6_AUTOCONF=yes
ONBOOT=yes

The important lines here to note are “MASTER=bond0“, and “SLAVE=yes” which tells that both eth0 and eth1 are now part of bond0 device.

5. Restart network and you are done!

[root@localhost ~]# service network restart
Shutting down interface eth0:                              [  OK  ]
Shutting down loopback interface:                          [  OK  ]
Bringing up loopback interface:                            [  OK  ]
Bringing up interface bond0:                               [  OK  ]
[root@localhost ~]# ifconfig
bond0     Link encap:Ethernet  HWaddr 00:16:3E:1C:C5:A7
          inet addr:192.168.122.118  Bcast:192.168.122.255  Mask:255.255.255.0
          inet6 addr: fe80::216:3eff:fe1c:c5a7/64 Scope:Link
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
          RX packets:80 errors:0 dropped:0 overruns:0 frame:0
          TX packets:54 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:11210 (10.9 KiB)  TX bytes:11630 (11.3 KiB)

eth0      Link encap:Ethernet  HWaddr 00:16:3E:1C:C5:A7
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:45 errors:0 dropped:0 overruns:0 frame:0
          TX packets:63 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3288 (3.2 KiB)  TX bytes:13120 (12.8 KiB)

eth1      Link encap:Ethernet  HWaddr 00:16:3E:1C:C5:A7
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:42 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:8384 (8.1 KiB)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:764 (764.0 b)  TX bytes:764 (764.0 b)

As you can see from the output of ifconfig, device bond0 is listed as MASTER while devices eth0 and eth1 are listed as SLAVE. Also, the hardware address of bond0 and its underlying devices eth0 and eth1 are the same (00:16:3E:1C:C5:A7). In case you have multiple bond devices, comparing the hardware address of that bond device with the actual network device (ethX) will tell you whether it is a part of that particular bonding or not.

Now, the current status of the bond device bond0 is present in /proc/net/bonding/bond0. Time to fool around with bonding now… :-)

[root@localhost ~]# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.2.4 (January 28, 2008)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:16:3e:1c:c5:a7

Slave Interface: eth1
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:16:3e:58:02:c7

As I have highlighted above, the bonding mode is active-passive (since I used mode=1 to configure it in modprobe.conf). Also, both interfaces are up, but current active slave is eth0. Now, what happens when I down eth0? Normally when we down an interface, the IP associated with it also goes down (becomes unreachable). However, in bonding, it just switches over to next slave, eth1 - keeping the connection and the IP active:

[root@localhost ~]# ifdown eth0
[root@localhost ~]# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.2.4 (January 28, 2008)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth1
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:16:3e:58:02:c7
[root@localhost ~]# ifup eth0
[root@localhost ~]# cat /proc/net/bonding/bond0 
Ethernet Channel Bonding Driver: v3.2.4 (January 28, 2008)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth1
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:16:3e:58:02:c7

Slave Interface: eth0
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:16:3e:1c:c5:a7

Notice that when I started eth0 again (ifup eth0), it got added to the bond device automatically. Also, in the above output, even though the permanent HW Address of eth0 and eth1 are different, they retain the HW address of the bond device in ifconfig output:

[root@localhost ~]# ifconfig
bond0     Link encap:Ethernet  HWaddr 00:16:3E:1C:C5:A7 
          inet addr:192.168.122.118  Bcast:192.168.122.255  Mask:255.255.255.0
          inet6 addr: fe80::216:3eff:fe1c:c5a7/64 Scope:Link
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
          RX packets:87 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:6340 (6.1 KiB)  TX bytes:4950 (4.8 KiB)

eth0      Link encap:Ethernet  HWaddr 00:16:3E:1C:C5:A7 
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:85 errors:0 dropped:0 overruns:0 frame:0
          TX packets:44 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:6360 (6.2 KiB)  TX bytes:6424 (6.2 KiB)

eth1      Link encap:Ethernet  HWaddr 00:16:3E:1C:C5:A7 
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:574 (574.0 b)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:764 (764.0 b)  TX bytes:764 (764.0 b)

That’s it..!! Happy bonding.. :)

 

How to disable IPv6

Both Red Hat Enterprise Linux 4 and 5 enable Internet Protocol Version 6 (IPv6) by default. Some users do not find it worth using, if that’s the case with you then you can always disable the same.

How to disable:
======================

To disable IPv6 support in RHEL 4, remove the following line, if it exists, from the /etc/modprobe.conf file.

alias net-pf-10 ipv6

and instead, add:

alias net-pf-10 off

to make sure that this module will not get loaded from now on. Reboot your RHEL 4 system now to complete the process.

However, if using RHEL 5, also add the following line to the /etc/modprobe.conf file:

alias ipv6 off

It is also a good practice to change the NETWORKING_IPV6 line in the /etc/sysconfig/network file to the following:

NETWORKING_IPV6=no

and also make sure that ip6tables does not start from the next reboot.

chkconfig ip6tables off

Now, reboot the RHEL 5 system to disable IPv6 support.

How to re-enable:
======================

Just undo the changes you made above!

 

up2date not connecting to RHN

For those who didn’t knew, two BIG things happened recently:

1. RedHat released RHEL 4.8

2. RedHat Network (RHN) moved into Akamai Content Delivery Network, boosting package download speeds (upto 10-14x in some regions!!) by enabling “location aware updates” which means that a package downloaded from RHN using yum or up2date will now be downloaded from the server which is closest to your geographical location.

So, what’s new? The latest up2date package, v4.8.1-33 which is aware of the RHN’s CDN and is coded to acknowledge URL redirects from RHN to a near-by mirror.

Sounds cool, but there’s a catch. Most of the servers have strict firewall rules which only allow connections from the main RHN host, xmlrpc.rhn.redhat.com. But with the introduction of CDN, if you update the up2date package to v4.8.x+, you will have to make sure that the server has access to these hostnames too (apart from xmlrpc.rhn.redhat.com) :

content-xmlrpc.redhat.com
content-web.rhn.redhat.com
content-satellite.rhn.redhat.com

Now if you do not do this, up2date is going to show you different kind of errors, mostly related with connection problems.

If you do not wish to make any changes to your firewall rules, then you can disable ‘Location Aware Updates’ for the system profile on RHN. It will make sure that your server will always connect to the main RHN host and download packages from there only instead of checking with CDN.

However, I for one will not recommend it since you will then be experiencing the old and sluggish package download speeds while your fellow admin will use CDN to download the same stuff 10x faster than you.. lol.. ;)

 

DNS Terms you need to know

During my beginning years of System Administration, I was pretty much confused by the terms ‘primary nameserver’, ’secondary nameserver’, ‘master/slave nameserver’ etc. Different websites have different views on these terms. I am sure many system admins (even experienced ones) have got their ideas wrong about these terms.

My confusion ended the day I stumbled upon Oreily’s DNS and Bind. This book is without doubt the best DNS related book in the world, and would recommend this book to anyone who wish to know more about DNS and its working. So, here we go:

A Name Server keeps information for the translation of computer names to IP addresses (even for reverse translations). The name server takes care of a certain part from the space of names of all computers. This part is called the zone (at minimum it takes care of zone 0.0.127.in-addr.arpa). A domain or its part creates the zone. The name server can with the help of an NS type record (in its configuration) delegate administration of a subdomain to a subordinate name server. The name server is a program that performs the translation at the request of a resolver or another name server. In UNIX, the name server is materialized by the named program. Also the name BIND (Berkeley Internet Name Domain) is used for this name server.

Types of name servers differ according to the way in which they save data:

> Primary name server/primary master is the main data source for the zone. It is the authoritative server for the zone. This server acquires data about its zone from databases saved on a local disk. Names of these types of servers depend on the version of BIND they use. While only the primary name server was used for version 4.x, a primary name master is used for version 8. The administrator manually creates databases for this server. The primary server must be published as an authoritative name server for the domain in the SOA resource record, while the primary master server does not need to be published. There is only one of this type of server for each zone.

> Master name server is an authoritative server for the zone. The master server is always published as an authoritative server for the domain in NS records. The master sever is a source of data of a zone for the subordinate servers (slave/secondary servers). There can be several master servers. This type of server is used for Bind version 8 and later.

> Secondary name server/slave name server acquires data about the zone by copying the data from the primary name server (respectively from the master server) at regular time intervals. It makes no sense to edit these databases on the secondary name servers, although they are saved on the local server disk because they will be rewritten during further copying. This type of name server is also an authority for its zones, i.e., its data for the particular zone is considered irrevocable (authoritative). The name of this type of server depends again on the version of BIND it uses. For version 4, only the secondary name was used, the term slave server was used for a completely different type of server. In version 8 you can come across both names.

> Caching-only name server is neither a primary nor secondary name server (it is not an authority) for any zone. However, it uses the general characteristics of name servers, i.e., it saves data that comes through its cache. This data is called non-authoritative. Each server is a caching server, but by the words caching, we understand that it is neither a primary nor secondary name server for any zone. (Of course, even a caching-only server is a primary name server for zone 0.0.127.in-addr.arpa, but that does not count).

> Root name server is an authoritative name server for the root domain (for the dot). Each root name server is a primary server, which differentiates it from other name servers.

> Slave name server (in BIND version 4 terminology) transmits questions for a translation to other name servers; it does not perform any iteration itself.

> Stealth name server is a secret server. This type of name server is not published anywhere. It is only known to the servers that have its IP address statically listed in their configuration. It is an authoritative server. It acquires the data for the zone with the help of a zone transfer. It can be the main server for the zone. Stealth servers can be used as a local backup if the local servers are unavailable.

 

Chkrootkit Installation Guide

chkrootkit (Check Rootkit) is a common Unix based program intented to help system administrators check their system for known rootkits. It is basically a shell script using common UNIX/Linux tools like strings and grep commands to check core system programs for signatures. If you doubt that your server has been hacked, chkrootkit is what you need to run.

Chkrootkit’s installation is very easy. I am describing the steps below.

1. Ssh to the server as ‘root’, and then wget the chkrootkit from its FTP location.

wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz

2. Unpack the tarball in the current directory.

tar xvzf chkrootkit.tar.gz

3. Go to the directory newly created, and compile the script.

cd chkrootkit*
make sense

4. Once the compilation is complete, use the below command to execute chkrootkit.

./chkrootkit

NOTE: Make sure that you have gcc and make on the server or else the installation will fail :-(

At this point, I would suggest that you set a crontab to execute this chkrootkit daily. You can even have the results sent to you via email.

For that, create a file /etc/cron.daily/chkrootkit.sh

Insert the following to the new file and save it:

#!/bin/bash
cd /yourinstallpath/chkrootkit-0.42b/
./chkrootkit | mail -s "Daily chkrootkit from Servername" admin@youremail.com

1. Replace ‘yourinstallpath’ with the actual path to where you unpacked Chkrootkit.
2. Change ‘Servername’ to the server your running so you know where it’s coming from.
3. Change ‘admin@youremail.com’ to your actual email address where the script will mail you.

Change the file permissions so that it can execute:

chmod 755 /etc/cron.daily/chkrootkit.sh

You will receive daily chkrootkit reports on your email address from now on.

 

How to close Open DNS

This tutorial describes how to close an Open DNS server. An Open DNS server allows anyone to use that server as a DNS lookup server. This is a potential threat and such access must either be blocked, or restricted to a few trusted IPs. This is how it is done.

1. Make a list of IPs you consider as trusted (i.e., only those IPs which can use this DNS server for DNS lookups). The list should include all IPs on the server. Now if you don’t know what I am talking about, ssh to your server, and type in the below command as root:

ifconfig | grep 'inet addr' | cut -f2 -d: | cut -f1 -d' ' | sort | uniq

2. Open /etc/named.conf in an editor. I would recommend that you take a backup of the file first before this.

cp -p /etc/named.conf /etc/named.conf.bak
vi /etc/named.conf

3. Locate this line:

key "rndckey" {
};

Move your cursor below this block of code, and press ‘i’ (to change into vi’s insert mode) and then type in the following:

acl "trusted" {
IP1; IP2; IP3; IP4; externalIP1 ;
};

Modify the line IP1; IP2; IP3; IP4; externalIP1 ; to include server’s IP addresses and any external IPs which you wish to allow recursive queries.

4. Once the acl “trusted” is added, move down the file and locate the block named options. Inside it add the below lines:

allow-recursion { trusted; };
allow-notify { trusted; };
allow-transfer { trusted; };

This is how the options block might look like once the changes are made:

options {
directory "/var/named";
allow-recursion { trusted; };
allow-notify { trusted; };
allow-transfer { trusted; };

dump-file “/var/named/data/cache_dump.db”;
statistics-file “/var/named/data/named_stats.txt”;
/*
* If there is a firewall between you and nameservers you want
* to talk to, you might need to uncomment the query-source
* directive below. Previous versions of BIND always asked
* questions using port 53, but BIND 8.1 uses an unprivileged
* port by default.
*/
// query-source address * port 53;
};

5. Save the changes (use ‘esc’ + ‘:wq’ in vi editor) and then restart named

/etc/init.d/named stop
/etc/init.d/named start

 

Ioncube Installation Guide

This article describes how to install ionCube loader extension in PHP. ionCube provides tools for PHP source code protection. Usually, a PHP file is in plain-text format. Which means anyone who has access to the actual PHP file can use a text editor (like vim) to view the source code.

If a skilled hacker/programmer gets access to the entire PHP source code, then it would allow him/her to find vulnerabilities which can be used to launch attack on website(s) or web server(s).

It was this reason which led to the web industry search for an encoding engine that is capable of translating source code to efficient bytecodes, and one of the best solution today is ionCube loader. ionCube encoding tools deliver the ideal combination of maximum source code protection without sacrificing performance, reliability or language compatibility.

By default, PHP is unable to parse files encoded using ionCube. In order to do so, you have to install ionCube loader extension in PHP. This is how it is done:

1. Download ionCube loader from ioncube.com

wget http://downloads2.ioncube.com/loader_downloads/ ioncube_loaders_lin_x86.tar.gz

2. Extract the tar.gz file

tar zxvf ioncube_loaders_lin_x86.tar.gz

3. Change to directory ‘ioncube’ and copy over the file ioncube-install-assistant.php to a web directory such as your hosting directory

cd ioncube/
cp ioncube-install-assistant.php /home/userdirectoryhere/public_html/

4. Then open it http://www.yourdomain.com/ioncube-install-assistant.php.
The output should be something similar to:

Analysis of your system configuration shows:

PHP Version 4.3.3
Operating System Linux
Threaded PHP No
php.ini file /usr/local/lib/php.ini
Required Loader ioncube_loader_lin_4.3.so

5. Now move the iconcube directory to a permanent location:

cd ../
mv ioncube /usr/local

6. Now that you know the location of php.ini you need to edit it.

pico /usr/local/lib/php.ini

Now find where other zend extentions are in the file.
ctrl + w: zend_extension

Paste in your new line for ioncube loader

zend_extension = /usr/local/ioncube/ioncube_loader_lin_4.3.so

7. Save the changes
ctrl + X then Y and enter

8. Restart the web server to take effect.

/etc/init.d/httpd restart

Now, create a new document named phpinfo.php. The file should contain the below lines:

phpinfo();
?>

Place this document in your www directory and open it from your web browser by pointing to http://www.yourdomain.com/phpinfo.php. You should now see ionCube loader listed in it (search for the string ‘ioncube’).

That’s it! :-)

 

How to disable Telnet

Telnet is a xinetd managed service which listens on port 23. You can login to your account on the server by using a telnet client. However, unlike ssh, telnet initiates a normal connection. i.e., the telnet data packets is in plain-text format, and can be captured easily by network monitoring applications.
If you are a system administrator managing a server, it is compulsory that you have telnet service disabled on it. This is how it is done:

1. Login to your server through SSH and su to root.

2. Type

vi /etc/xinetd.d/telnet

3. Look for the line:

disable = no

and replace with

disable = yes

4. Now restart the xinetd service:

/etc/init.d/xinetd restart

5. Turn off it through chkconfig as well because it can still start during the next reboot.

/sbin/chkconfig telnet off

 

Email alert on root login

Do you wish to be notified by email whenever someone login to the server as root? The tip that you read below is useful if more than one admins know the server root password, and you want to know when and where they access the server from.

To make this possible, just edit the file /root/.bashrc and add the below line at the end of the file:

echo 'ALERT - Root Shell Access (YourserverName) on:' `date` `who` | mail -s "Alert: Root Access from `who | cut -d"(" -f2 | cut -d")" -f1`" you@yourdomain.com

Replace ‘YourServerName‘ with the handle for your actual server and ‘you@yourdomain.com‘ with your actual email address.

How does this work? You may ask! /home/<user>/.bashrc is one of the scripts executed when a successful login for that user occur. Since we have to be alerted during root logins, we place this code at the end of /root/.bashrc.

Consider the case that you wish to be alerted when a user, say ‘joe‘ login to his account. In that case you can paste the one line code to /home/joe/.bashrc.