Saturday, March 10, 2012

Implement Disk Quotas

Implement Disk Quotas in RHEL 6 and CentOS 6

Quotas are used to limit a user's or a group of users' ability to consume disk space. This prevents a small group of users from monopolising disk capacity and potentially interfering with other users or the entire system. This feature of Linux allows the system administrator to allocate a maximum amount of disk space a user or group may use. It can be flexible in its adherence to the rules assigned and is applied per filesystem. The default Linux Kernel which comes with Redhat and Fedora Core comes with quota support compiled in. In order to implement quotas you need to check whether the kernel supports them.

Check whether the quota support is built into the kernel

[root@server1~] # grep CONFIG_QUOTA /boot/config-2.6.18-1.2798.fc6
Those two values should be 'y'. If its not you may need to install the quota rpm package or you may have to recompile your kernel.


  • You should have a seperate unique partition to implement quotas and mount the partition.
  • Make necessary changes in /etc/fstab file and remount the partition and check that quotas are on.
  • Create files aquota.user and in mounted partition folder. [ Note: this may not be required for RHEL5 ]  and make sure the owner of those files in root and he should be able to read and write to those files ( chmod 600 aquota.*).
  • Run the command quotacheck to check that quotas are implemented.

Create a seperate partitiion

Using your favorite partitiion tool like ( fdisk, parted, gnuparted or any other tool create a partition). Create a directory and mount that partition to that directory.

[root@server1~] # mkdir -p /partmount
[root@server1~] # mount /dev/sda7 /partmount

Changes to /etc/fstab

In order to impletment quotas on the partition you need to make changes to /etc/fstab so that when you reboot the system, the quotas are still there on the filesystem. This step is required if you intend to make the quotas permenant. Change the last line as shown in the example.

[root@server1~] # vim /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
sysfs                   /sys                    sysfs   defaults        0 0
LABEL=SWAP-hdb1         swap                    swap    defaults        0 0
/dev/sda7  /partmount  ext3 defaults,usrquota,grpquota  0 0

Now we need to remount the partition for the quotas to be implemented.

[root@server1~] # mount -o remount /partmount

Creating quota related files

[root@server1~] # cd /partmount
[root@server1 partmount] # touch aquota.user; touch
[root@server1 partmount] # chown root:root aquota.*; chmod 600 aquota.*

Check that quotas are working

[root@server1~] # quotacheck -vgum /partmount

Implementing Quotas for users and groups

edquota command

To specify disk quotas you need to run either edquota or setquota commands. In order to specify quota for the user henry you will use the command edquota as follows.

[root@server1~] # edquota -u henry

You will be presented with the vi editor specifying the soft limit the hard limit and inodes ( the number of files ) soft limit and hard limit.

Soft Limit: This is the maximum amount of space a user can have on that partition. If you have set a grace period, this will act as an alarm, and you will also be required to set a hard limit.

Hard Limit: Hard limits are only neccessary when you are using grace periods. If grace periods are used this will be the absolute limit a user can use.

Grace periods are set by using the command edquota -t /partition

The edquota command can also be used to copy quota settings for one user as a template to any number of users in your system You will need to use -p switch of the edquota command to copy quota settings.

[root@server1~] # edquota -up user1 user2 user3 user4

setquota command

Alternatively you can use the setquota command to set quotas on users and groups.

[root@server1~] # setquota -u user1 0 0 0 0 /partmount

To set a quota of 4GB to user henry we would use the following command

[root@server1~] # setquota -u henry 4194304 4194304 0 0  /partmount
Its important to remember to calcuate Megabytes in times 1024 X 1MB and Gigabytes as (1024)2 x 1GB

To set 240Msoft, 256M hard for user jerry

[root@server1~] # setquota -u jerry 245760 262144 0 0 /partmount

Reporting quotas

Reports on quotas allocated to users and groups could be obtained by using the command repquota

[root@server1~] # repquota -u /partmount

To obtain individual quota for users jerry and group payroll the commands would be as follows:

[root@server1~] # repquota -uv jerry
[root@server1~] # repquota -gv payroll

Quota management

Quotas management can be done with the command quotacheck. This command is useful in the sense we can check that the quotas that are allocated are really in the pipeline for execution.

[root@server1~] # quotacheck -vgum /partmount

Configure a Caching Only DNS Server

Caching-Only DNS Server

A caching-only name server is used for looking up zone data and caching (storing) the result which is returned. Then it can return the answers to subsequent queries by using the cached information.

A caching-only server is authoritative only for the local host i.e, but it can automatically send requests to the Internet host handling name lookups for the domain in question.

In most situations, a caching-only name server sends queries directly to the name server that contains the answer. Because of its simplified nature, a DNS zone file is not created for a caching-only name server.

Running the Caching-only Name Server in an chroot environment is a secure approach. The chroot environment has more security compared to the normal environment.

To configure the /etc/named.conf file for a simple caching name server, use this configuration for all servers that don't act as a master or slave name server. Setting up a simple caching server for local client machines will reduce the load on the network's primary server. Many users on DSL connections may use this configuration along with bind for such a purpose. Ensure that the file /etc/named.conf highlights the entries below:

Terminal Window View
options {
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
forwarders {;; };
forward only;
// a caching only nameserver config
controls {
inet allow { localhost; } keys { rndckey; };
zone "." IN {
type hint;
file "";
zone "" IN {
type master;
file "named.local";
allow-update { none; };

With the forwarders option, and are the IP addresses of the Primary/Master and Secondary/Slave DNS server on the network in question. They can also be the IP addresses of the ISPs DNS server and another DNS server, respectively. With the forward only option set in the named.conf file, the name server doesn't try to contact other servers to find out information if the forwarders does not give it an answer.  To test this setup try the following commands

[] # chkconfig --levels 25 named on
[] # service named restart

We have now turned on the named server for persistent reboots and started the service for the current session. Now to test whether the caching - named server is working or not lets see:

Terminal Window View
# nslookup
Server: localhost

Server: localhost

nslookup now asked the named to look for the machine It then contacted one of the name server machines named in the root.cache file, and asked it's way from there. It might take a while before the result is shown, as it searches all the domains the user entered in /etc/resolve.conf. When tried again, the result should be similar to this example:

Terminal Window View
Server: localhost
Non-authoritative answer:

Note the Non-authoritative answer in the result this time. This means that named did not go out on the network to ask this time, it instead looked up in its cache and found it there. But the cached information might be out of date. So the user is informed of this danger by it saying Non-authoritative answer. When nslookup says this the second time when a user ask for a host, it is a sign that it caches the information and that it's working. Now exit nslookup by giving the command exit.

Create your own private yum repository.

Create your own private yum repository

Sometimes, especially when you create your own RPMs, it is extremely useful to keep them in a local YUM repository . The advantage of this is that, when you install a package, YUM automatically resolves any dependencies, not only by downloading the necessary packages from the other repositories you might have in you list, but also by using your local repo as a resource for potential dependencies.

So, when installing a package (eg my_package.rpm ) with YUM, you are supposed to have already created RPM packages for all of the my_package.rpm 's dependencies and to have updated the repository's metadata, so that yum is able to resolve all the dependencies. If these dependencies do not exist in any of the repositories in your list, then, in short, you cannot install your package with yum.

So, in order to install an RPM package and all the other packages that it depends on, you only need to run:

# yum install my_package.rpm

How to create a local YUM repo ?

You will need an utility, named createrepo . Its RPM package exists in Fedora Extras. To install it, just run as root:

# yum install createrepo 

Then, put all your custom RPM packages in a directory. Assuming that this directory is /path/to/repository , you can create all the necessary metadata for your local repository by running the following command as root or as the user that owns the directory:

# createrepo -v /path/to/directory

That's it! Your local YUM repository is ready.

Keep in mind that every time you put any new RPMs in that directory or remove any old RPMs, you will need to run the above command again, so that the repository metadata gets updated.

Add your local repo to the list

The next thing you need to do is to add your local repository to your list of repos, so that yum knows where to find it. This info is kept in the /etc/yum.repos.d/ directory. As root, create a new text file in this directory, name it fedora-local.repo (you can use any name you like, but remember to add the extension .repo ), and add the following info in it:

[]# cat /etc/yum.repos.d/fedora-local.repo
name=[give any name you like without the square brackets ofcourse]
baseurl=[file:| ftp | http |<path to the repository>] 
In Order to access the repository over ftp or http the urls should be modified as follows

As you can see, we used the protocol file:/// in the baseurl option. This assumes that the local repo exists in the local machine. If it exists in another machine of your internal network, feel free to use any other protocol in order to tell yum where to find your local repository, For example you can use http:// , ftp:// , smb:// etc.

In the above example, the GPG key check is disabled ( gpgcheck=0 ). If you sign your packages, you can set this to " 1 " and uncomment the following line ( gpgkey=... ). This contains the path to your public key, so that YUM can verify the package signatures.

You can have as many local YUM repositories as you like.

Other uses of a local repository

Using a local repository does not only serve as a place for your custom RPMs. You can perfectly save some bandwidth by downloading all the released fedora updates in that repo and use this to update all the systems of your internal network. This will save bandwidth and time.

The Procedure is the same for all RPM based systems, using YUM Package Manager. So this can be applied to Fedora, Redhat and CentOS systems

Understanding DNS ACL Directives

Understanding Bind DNS ACL Directives

An ACL or access control list can be used in DNS to restrict unwanted queries to the DNS server

  • In its simplest form, an ACL assigns a name to an address match list.
  • Can generally be used in place of a match list (nesting is allowd).
  • Best practice is to define ACL's at the top of /etc/named.conf.

Address Match List

A semicolon-seperated list of IP Addresses or subnets used with security directives for host based access control.


  • IP Address :
  • Trailing dot: 192.168.0.
  • CIDR: 192.168.1/24 [Classless InterDomain Routing]
  • Use a bang (!) to denote inversion / negation.

Example Declaration

The following ACL defines a trusted host:
acl  "trusted"          {; };

The following ACL defines a trusted domain or network
acl  "classroom"   {; trusted; };

This ACL defines an untrusted network or domain
acl  "cracker"          {; };

This ACL defines the MASTER DNS SERVER
acl  "mymasters"     {; };

Usage as follows:

The above ACL's can be used with the following directives in the /etc/named.conf as:

Option:  listen-on port 53 { trusted; };
The option above states that the DNS is setup on "trusted" ACL and you are configuring Bind to listen to IP address of the same system.

Option:  allow-query { classroom; !cracker; };
The option above will allow queries from all hosts that are in the "classroom" ACL but not from "cracker" ACL.

Option:  allow-transfer { classroom; !cracker; };
The option above will allow zone transfer to Slave DNS servers in the "classroom" ACL but not to"cracker" ACL.

Option:  forwarders { classroom; !cracker; };
The option above will forward queries "classroom" ACL but not to"cracker" ACL.

Likewise you can form ACL's and fine tune and restrict you DNS server so as to deny unwanted domains and queries.

Basic PXE Install Server

Basic TFTP PXE DHCP Setup in Redhat 6 and CentOS 6

In order to prepare a Normal PXE Server we need the following Servers and Services to be set up prior to proceeding further.

  • Install NFS, FTP, HTTP and related packages.
  • Install TFTP Server and related Packages
  • Install DHCP Server and related Packages

Setting up the Network Server  [ NFS | FTP | HTTP ]

First, configure an NFS, FTP, or HTTP server to export the entire installation tree for the version and variant of Linux to be installed.

We are going to use NFS simply because there are fewer steps involved. You are free to use any server to your liking, infact I recommend to install all the Servers and see for your self.

[] # yum install nfs-utils*
[] # chkconfig portmap on
[] # chkconfig nfs on
[] # service portmap restart
[] # service nfs restart

Create a directory /Linix_Distros/Osdir and dump the contents of the Linux DVD / Linux CD’s in that directory. And export the directory of /Linux_Distros to your local Network

Your /etc/exports file should look like this.

Terminal Window View
[] # cat /etc/exports
/Linux_Distros  *,sync)

Setting up the TFTP Server and related packages

Install the TFTP server and the related packages with the following commands.

[] # yum install tftp*

Before we move on we need to configure the tftp-server so that it will be started when the the system boots. First of all we need to enable the tftp-server so that its running in the first place. To do this we need to go to /etc/xinetd.d/tftp file and change the disable=yes to disable=no and then restart the xinetd service. Just check the following to see how to do that.

Terminal Window View
[] # cat /etc/xinetd.d/tftp
# default: off
# description: The tftp server serves files using the trivial file transfer \
# protocol.  The tftp protocol is often used to boot diskless \
# workstations, download configuration files to network-aware printers, \
# and to start the installation process for some operating systems.
service tftp
 socket_type  = dgram
 protocol  = udp
 wait   = yes
 user   = root
 server   = /usr/sbin/in.tftpd
 server_args  = -s /tftpboot
 #change the following to 'no'
 #disable  = yes
 disable          = no
 per_source  = 11
 cps   = 100 2
 flags   = IPv4

Then restart the xinetd service.

[] # chkconfig --levels 35 xinetd on
[] # service xinetd restart

Create a directory /tftpboot and under it create another directory pxelinux.cfg so the path looks like this
/tftpboot/pxelinux.cfg for clarity look to the following.

[] # mkdir -p /tftpboot/pxelinux.cfg

You will need to find the vmlinuz and initrd.img files in the /Linux_Distros/Osdir directory and copy them into the /tftpboot directory. These files will be used to start the kickstart process after the PXE boot has taken place.

Suppose we have a Red Hat Enterprise Linux™ 5 installation then my path should be /Linux_Distros/RHEL5 and I would find the vmlinuz and initrd.img in the following locations /Linux_Distros/RHEL5/images/pxeboot

Please note that the vmlinuz kernel must match the version of OS you are going to build.
[] # cp /Linux_Distros/RHEL5/images/pxeboot/initrd.img\
[] # cp /Linux_Distros/RHEL5/images/pxeboot/vmlinuz\

Booting a PC without a kernel written to a disk requires the use of PXE boot. And this can be achieved by installing the syslinux package. This package if not installed,  install it with the following command.

[] # yum install syslinux*

The component that is needed from this package to perform a PXE boot is pxelinux.0   Run a search for this file under the entire / directory. Once found copy the file to /tftpboot.

[] # cp /var/lib/syslinux/pxelinux.0 /tftpboot

Setting up the DHCP Server and related packages

Install a DHCP server that allows bootp onto the Linux Server. If a compatible DHCP package cannot be found on the installation disks, one can be downloaded at

The installation of the DHCP server should create an example of /etc/dhcpd.conf. The dhcpd.conf file is configuration file for the DHCP server. Rename this file and create a new one with the same name.  For the sake of your convinience I have provided one below.

Terminal Window View
ddns-update-style none;
ignore client-updates;

option domain-name  "";
option domain-name-servers;
default-lease-time 21600;
max-lease-time 43200;

########## IMPORTANT FOR PXE BOOTING ###############
allow booting;
allow bootp;

subnet netmask {

# --- default gateway
option routers;
option subnet-mask;

########## VERY IMPORTANT FOR PXE BOOTING ##########
filename "pxelinux.0"; 
########## IMPORTANT FOR PXE BOOTING ###############

Create a Kickstart File

You can create a Kickstart file from the system-config-kickstart if your are using Redhat or Fedora. Create a Kickstart file and name it ks.cfg or alternatively you can rename the anaconda-ks.cfg found in your root directory as a template for your ongoing installations.

Make the ks.cfg available though FTP,HTTP or NFS. For this we will use NFS and make it available through the /Linix_Distros directory since its exported already.

Once the client machine obtains the PXE environment specified in the dhcpd.conf file it begins to make tftp requests for a file named after its’ IP address in uppercase hexadecimal format. The hexadecimal file needs to be contained in the /tftpboot/pxelinux.cfg directory.

For example: The IP that was used for this document was The file that the machine then requested was /tftpboot/pxelinux.cfg/C0A80219 .

Incase you have not configured dhcp entries for each station in your network the pxelinux environment looks for a default file located in the /tftpboot/pxelinux.cfg/default. Create one to avoid confusion.

It should contain the following

Terminal Window View
[] # cat /tftpboot/pxelinux.cfg/default
default ks
prompt 0
timeout 600
label ks
kernel vmlinuz
append ks=nfs: initrd=initrd.img

Once the kernel is loaded an nfs mount is performed and the kickstart information is pulled from the specified the location.

CONGRATULATIONS you have now configured a TFTP,DHCP,NFS PXE Server to distibute the OS to a wide range of clients simultaneously, for unattended installations.

VsFTPD Virtual Server

Mysql Virtual Hosting, Individual User Directories and SSL Authentication with Chmod facility in Redhat6 and CentOS 6

Step 1: Install the required packages

  • Vsftpd
  • pam_mysql (for supporting mysql backend through pam)
[]# yum install vsftpd* pam_mysql

Step 2: Create Mysql database for Vsftpd

[]# mysql -u root -p
Enter password: 
#after entering the password you will get a 'mysql>' prompt
# type the following here
mysql > create database vsftpd;
#database will be created.
        TO 'vsftpd'@'localhost' IDENTIFIED BY 'ftpdpass';
        TO 'vsftpd'@'localhost.localdomain' IDENTIFIED BY 'ftpdpass';

Replace the string ftpdpass with whatever password you want to use for the MySQL user vsftpd. Still on the MySQL shell, we create the database table we need (yes, there is only one table!):

mysql > USE vsftpd;
mysql > CREATE TABLE `accounts` (
`username` VARCHAR( 30 ) NOT NULL ,
`pass` VARCHAR( 50 ) NOT NULL ,
# table will be created
mysql > quit ; 

As you may have noticed, with the quit; command we have left the MySQL shell and are back on the Linux shell.

Step 3: Create a virtual user virtualftp

First we create a non-privileged user called virtualftp (with the homedir /home/virtualftp ) belonging to the group virtualftp. We will run vsftpd under this user, and the FTP directories of our virtual users will be in the /home/virtualftp directory (e.g. /home/virtualftp/user1 , /home/virtualftp/user2 , etc.).

[]# useradd -d /home/virtualftp -s /sbin/nologin virtualftp

Then we make a backup of the original /etc/vsftpd.conf file and create our own:

[]# cp /etc/vsftpd/vsftpd.conf \
[]# cat /dev/null > /etc/vsftpd.conf
[]# vi /etc/vsftpd.conf
# Enter the following in vsftpd.conf file.

#ftpd_banner=Welcome to FTP SITE



The configuration options are explained on The important options for our virtual setup are chroot_local_user, guest_enable, guest_username, user_sub_token, local_root, and virtual_use_local_privs.

With the user_config_dir option you can specify a directory for per-user configuration files that override parts of the global settings. This is totally optional and up to you if you want to use this feature. I have not used this feature here so I put the # characher in front of the user_config_dir option.

Step 4: Configuring PAM to use Mysql

Now we must configure PAM so that it uses the MySQL database to authenticate our virtual FTP users instead of /etc/passwd and /etc/shadow. The PAM configuration for vsftpd is in /etc/pam.d/vsftpd. We make a backup of the original file and create a new one like this:

[]# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd_orig
[]# cat /dev/null > /etc/pam.d/vsftpd
[]# vi /etc/pam.d/vsftpd

# this sould have the following line
auth required /lib/security/ user=virtualftp passwd=virtualftp \
     host=localhost db=vsftpd table=accounts usercolumn=username \
     passwdcolumn=pass crypt=2
account required /lib/security/ user=virtualftp passwd=virtualftp \
     host=localhost db=vsftpd table=accounts usercolumn=username \
     passwdcolumn=pass crypt=2

Please make sure mysql password is the same as the one you used in mysql previously

Afterwards, we restart vsftpd:

[]# service vsftpd restart

Step 5: Creating the first virtual user

To populate the database we have to go back to the MySql shell again, login as before and follow the instructions below.

mysql > use vsftpd;
database changed
mysql > INSERT INTO accounts (username, pass) VALUES('Jimi', PASSWORD('secret'));
query successful

Jimi's homedir is /home/virtualftp/Jimi; unfortunately vsftpd doesn't create that directory automatically. Therefore we create it manually now and make it owned by the virtualftp user and the virtualftp group:

[]# mkdir /home/virtualftp/Jimi
[]# chown virtualftp:virtualftp /home/vsftpd/Jimi

For database administration you can use PhpMyAdmin web interface to manage your users more time efficiently.

Now open your FTP client program on your work station (something like WS_FTP or SmartFTP if you are on a Windows system or gFTP on a Linux desktop) and try to connect. As hostname you use (or the IP address of the system), the username is Jimi , and the password is secret . And remember use the port 990 to connect and check whether Auth-SSL is selected to authenticate.

If you are able to connect - congratulations! If not, something went wrong.

SSL and CHMOD notes below

To create a rsa certificate you would have to go to the /etc/pki/tls/certs directory and give a make command over there to get a vsftpd.pem

[]# cd /etc/pki/tls/certs
[]# make vsftpd.pem

Note from Step 3 the SSL section this settings will force local logins to use SSL

Users on this server can change the permissions of thier files through the client program
chmod_enable and virtual_use_local_privs are the directives needed to accomplish that.