Monday, April 9, 2007

Linux Quota

Quota is used to limit the disk space used by a user or group on a particular file system, thus giving system administrators better control over their disk usage policies. The quota package helps implementing quota for Linux.

The first step in setting up quota is to enable quota for a file system partition. To do this, either remount the file system with appropriate mount options, or edit /etc/fstab to make the changes permanent.

Suppose your home partition is mounted on the file system /dev/hda5 and you want to enforce quota for users. Mount the file system with quota options,

/etc/fstab

/dev/hda5 /home ext3 defaults,usrquota,grpquota 0 0

usrquota : Enables per user quota
grpquota : Enables per group quota

Remount home partition
[root@LinuxBox1 ~]#mount -o remount /home
[root@LinuxBox1 ~]#mount|grep /home
/dev/hda5 on /home type ext3 (rw,usrquota,grpquota)

Quota information for a file system is stored in files aquota.user and aquota.group files under the root of the file system, in this case /home. This files will be owned and accessible only by root. You have to initialise these files first using quotacheck command.
[root@LinuxBox1 ~]#quotacheck -vgum /home
quotacheck: Scanning /dev/hda5 [/home] done
quotacheck: Checked 1708 directories and 8935 files
If you are using this command for the first time, you may see some errors about file not in correct format/missing. Its ok.
[root@LinuxBox1 ~]#ls -la /home/aquota*
-rw------- 1 root root 9216 Apr 10 04:44 /home/aquota.group
-rw------- 1 root root 8192 Apr 10 04:44 /home/aquota.user

Enable quota on /home partition with quotaon command
[root@LinuxBox1 ~]#quotaon /home
/dev/hda5 [/home]: group quotas turned on
/dev/hda5 [/home]: user quotas turned on

Now everything is set up correctly, we can set quota for user 'safeer' using edquota command. This will open a file in your default editor (most probably 'vi '). You have to change its values appropriately.
[root@LinuxBox1 ~]#edquota -f /home -u safeer
Disk quotas for user safeer (uid 507):
Filesystem blocks soft hard inodes soft hard
/dev/hda5 1020 0 0 14 0 0

blocks : Space in 1k blocks used by the user (Current usage is 1MB)
inodes : Number of files/folders created by user (14 files/folders in total)
soft : Warning limit of space used/number of files created by the user. User gets a warning when this limit is reached, but he can still create/modify files.
hard : Maximum of space used/number of files created by the user. User can't cross this limit.

Let us enforce a soft limit of 4 MB and hard limit of 5 MB on space usage.
[root@LinuxBox1 ~]#edquota -f /home -u safeer
Disk quotas for user safeer (uid 507):
Filesystem blocks soft hard inodes soft hard
/dev/hda5 1020 4096 5120 14 0 0
Note that we are not restricting the number of inodes

Let us check this by creating files as safeer
[root@LinuxBox1 ~]#su - safeer
[safeer@LinuxBox1 ~]$quota
Disk quotas for user safeer (uid 507):
Filesystem blocks quota limit grace files quota limit grace
/dev/hda5 1020 4096 5120 2 0 0
Users can use quota command to view his current quota usage and quota limits as above.
'safeer' is already using 1MB of disk space. Let us create a file of 2MB:
[safeer@LinuxBox1 ~]$dd if=/dev/zero of=./temp1 bs=1024 count=2048
2048+0 records in
2048+0 records out
2097152 bytes (2.1 MB) copied, 0.024208 seconds, 86.6 MB/s
This will work fine since user has not exceeded the quota limit.
Now create another file of 1.5MB, making the total disk usage 4.5 MB (exceeds softlimit of 4MB)
[safeer@LinuxBox1 ~]$dd if=/dev/zero of=./temp2 bs=1024 count=2560
hda5: warning, user block quota exceeded.
2048+0 records in
2048+0 records out
2097152 bytes (2.6 MB) copied, 0.024208 seconds, 86.6 MB/s
Again create another file of size 1MB, thus exceeding the hard limit:
[safeer@LinuxBox1 ~]$dd if=/dev/zero of=./temp3 bs=1024 count=1024
hda5: write failed, user block limit reached.
dd: writing `./temp3': Disk quota exceeded
497+0 records in
496+0 records out
507904 bytes (508 kB) copied, 0.007349 seconds, 69.1 MB/s
If you want to set quota based on inode or both inode & space in the same way.
You can also set quota for group using the command
[root@LinuxBox1 ~]#edquota -f /home -g developers
This will edit the quota for group 'developer'. One thing people often misunderstand is that group quota means total space/inodes used by all members of a group. But actually it is the size/inodes used by users who have this group as primary group.

Administrators will frequently need to check the status of user quotas.
To find out the quota usage of a particular user:
[root@LinuxBox1 ~]#quota -u safeer
Disk quotas for user safeer (uid 507):
Filesystem blocks quota limit grace files quota limit grace
/dev/hda5 5008* 4096 5010 6days 5 0 0

Similarly use -g option instead of -u to find the quota of a group
Instead of individual quota reports, you can get the quota report for the entire filesystem:
[root@LinuxBox1 ~]#repquota /home
*** Report for user quotas on device /dev/hda5
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 1172676 0 0 6109 0 0
vinu -- 239188 0 0 4347 0 0
safeer +- 5008 4096 5010 6days 5 0 0
nebu +- 5120 4096 5120 6days 4 0 0

This will list each users current usage as well as the limit for usage. Using repquota with -g option will give the group quota report. Use '-a' option to list quota of all patitions.

You can use the command warnquota to sent mail to all users who have exceeded quota. The message sent can be customeised by editing the file /etc/warnquota.conf. You should set an administrator for each group so that this administrators will be emailed when their groups exceed the quota (use command: warnquota -g). You can do this by editting /etc/quotagrpadmins, syntax of the file is group:admin_user.

Monday, April 2, 2007

Basics of Samba configuration

Samba is a file sharing service in linux that uses SMB (Server Message Block) protocol. Both windows and linux support SMB protocols. So this service can be used for file sharing between two linux machines or linux and windows machines. In addition to file sharing samaba can also be used to share printers in network. It can also act as a Domain controller or client in an active directory environment.

Samba runs two daemons, smbd (SMB daemon) & nmbd (Netbios naming daemon). They listen on 4 ports as listed below

Netbios Name Service: netbios-ns 137
Netbios Datagram Service: netbios-dgm 138
Netbios Session Service: netbios-ssn 139
Microsoft Active Directory Service: microsoft-ds 445

The main configuration file of samba is /etc/samba/smb.conf. It contains a number of sections, starting with a section name enclosed in square brackets and containing one or more key/value pair seperated by equal sign.

The [global] section contains settings that are applied server wide. The most common of them are listed below:

workgroup: The name of the windows work group to which this samba server should belong. This name will be shown in a windows machines My Network Places -> Entire Network -> Microsoft Windows Network.
Eg:
workgroup = Linux Shares

We can also set a description about this particular server using (This is optional)
server string = Linuxbox1_WinShare

As part of security measures, you should restrict which networks or machines have access to this share. Here we will allow our local network 192.168.0.0/24 and the local loop.
host allow = 192.168.0. 127.

We can share a directory through samba with the following syntax (minimal)
[sharename]
comment = Comment about this share
path = /path/to/directory/to/be/shared

We can use many other configuration parameters to change the properties of this share, some of them are:

read only = [yes]/[no] :If yes, permits only read access to the share
writable = [yes]/[no] : If yes, data can be written to the share

By default all shares will have read only permission. The above two are actually complements of each other.

bowsable = [yes]/[no] : Whether the share should be visible in when browsing machine resources, set to 'yes' by default.
hide dot files = [yes]/[no] : If yes, hides unix hidden files in windows also. Set to 'no' by default.

In places where you can provide a list of values, separate each value by space.

admin user = admin1 admin2 ..... : Users allowed to act as root (for the share)
valid users = user1 user2 ..... : Users allowed to access the share
invalid users = root nfs mail .... :Users not allowed to access the share.
read list = user1 user2 ..... : Users who have read only permission on the share
write list = user 5 user6 ... : Users who have write permission to the share.

You can grant permission to members of a group instead of a long list of users. If you want to grant write permission on a share to the accounts group members, add the following line to the share section.
write list = @accounts

Samba uses separate user database (when the variable "security = user" is set - default ) stored in /etc/samba/smbpaswd. This database is manipulated by the command smbpasswd. To add a user to samba database, he should be present in the system user database (/etc/passwd). Some useful options of smbpasswd are:

-a : Add a samba user
-x : Delete samba user
-d : Disable samba user
-e : enable samba user

[root@LinuxBox1 ~]#smbpasswd -a safeer
New SMB password:
Retype new SMB password:
Added user safeer.

The share [homes] is a special share which lets the users to access their home directories via samba.

[homes]
browsable = no
writable = yes

The user home directories will not be visible in the browse list, but authenticated users will be able to see their home directory.

[printers] is another special session used to share the printers configured on the samba server. When a request comes for a printer, samba will search the Unix printer capability file (/etc/printcap usually), and automatically use each printers listed in the file. The minimum configuration required for printing is

[printers]
printable = yes
path = /var/spool/samba
printcap name = /etc/printcap
public = no
valid users = user1 user2 user2

If you want to add a separate printer

[hp-accounts]
printable = yes
path = /var/spool/samba/hp-3500
printer = hp-3500
valid users = @accounts

This will create a printer share hp-accounts accessible only by accounts department.

Restart samba service, when smb.conf is changed

[root@LinuxBox1 ~]#service smb restart

Wednesday, March 28, 2007

Linux user management

The primary user database in Linux systems is /etc/passwd. The file reserves a single line for each user account and each line contains 7 fields seperated by colons. Let us see a single line extract from the passwd file.

enterprisedb:x:517:523:Enterprise Database Server:/home/enterprisedb:/bin/bash

Field 1 - enterprisedb : Username/loginname of the account


Field 2 - x : In older linux versions this filed was used to store passwords (in encrypted format), but rescent systems store this in a seperate file /etc/shadow to which only root has access permissions. Now the 'x' character indicate that the password is stored seperately (reffered to as password shadowing).

Field 3 - 517 : Numeric user id. Associated with every user/group account will be a numeric identifier called user id / group id.

Field 4 - 523 : Numeric group id of user's primary group.

Field 5 - Enterprise Database Server : Comment section or additional information section, can contain any inforamtion about the user (usually his Real name or, purpose of account if it is a system/service account). Here the user enterprisedb was created when I installed enterprise database on my server. Hence the comment Enterprise Database Server.

Field 6 - /home/enterprsiedb : Home directory of the user

Field 7 - /bin/bash : The shell from which the user can execute commands when he is logged in

We need to manipulate this database (and many more) for adding, modifying and deleting user accounts from the system. Linux provides many handy command line tools for this.

useradd

Used to add users to the system, you can change all the 7 fields of the passwd file using this command.

Syntax:
useradd [options] LOGIN
useradd -D [OPTIONS]


The first syntax is used to adding an account to the system

options :

-c comment : Add additional information or comment about the user (blank by default)

-b HOME_DIR: The prefix path that will be appended to username to make the full path to users home directory. The default is "/home". Thus the user "safeer" will have home directory /home/safeer by default.

-d HOME: complete path to homedirectory

-e EXPIRE DATE: the expiration date for the account.

-f INACTIVE: number of days after which the accoount will be disabled once the password is expired.

-g GID: Group id/group name to which the user should belong (this group should already exist) of the user (automatically assigned by default)

-G group1,[group2]....... : List of additional groups the user is a memebr of

-p password: the password for the account in the irreversible crypt format. This option is not recommented, instead use passwd command.

-s shell : The shell used by the account. To find out the shells availiable in your machine, check /etc/shells (can be listed using the command chsh -l).

-u UID : User's numeric userid

there are a lot more options, to obtaim a complete list use man pages

One special feature of useradd availiable in Redhat systems is the User Private Group (UPG) scheme which creates a unique group for every user created, and the user will be the only memebr of that group. This adds a certain level of security to user permissions. To turn off this behaviour use the option -n.

The second syntax is used to set the default values for useradd. When specified without any options, it will display current default values. There are only limitted number of options.

-b HOME_DIR: The home directory prefix

-e EXPIRE DATE: the expiration date for the account.

-f INACTIVE: number of days after which the accoount will be disabled once the password is expired.

-g GID: Group id

-s SHELL: shell

Consider an example where the user baiju will be added to the system with following criteria:
He should be the member of developers group, he should also be a memeber of staff group
His home directory should be /usr/dev/baiju
He should have cshell as his login shell

[root@LinuxBox1 ~]#useradd -d /usr/dev/baiju -s /bin/csh -G developers,staff baiju

Now, set password for baiju
[root@LinuxBox1 ~]#passwd baiju
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.


Instead of setting all the options when the user is first created, we can simply create a user with default options and modify the user properties later as and when the need arises. We can use the usermod command for this

usermod

Syntax:
usermod [OPTIONS] login

login : user loginname

OPTIONS:

many options of the useradd command are applicable here, they include -[c/d/e/f/g/G/p/s/u]. Othe options are:

-l login_name : Change user login name. If we want to change the login name 'baiju' to 'baijujohn'
use
[root@LinuxBox1 ~]#usermod -l baijujohn baiju

-L : lock user password, effectively disabling the user login
-U : unlock the user locked by -L option


If you want to change a users login shell later you can use "usermod -s /bin/ksh login_name". Linux provides another command for achieving this - 'chsh':
[root@LinuxBox1 ~]#chsh -s /bin/ksh baiju

To remove a user use userdel command

userdel

Syntax:
userdel [-r] login

-r : if this option is used the user's home directory and mail spool will be deleted from the system. User's files in other locations wil have to be removed manually. (Use find command with user UID as search criteria)

The files affected by above commands are /etc/passwd, /etc/shadow, /etc/groups

You can manually edit /etc/passwd & /etc/shadow using the command "vipw".


Friday, March 16, 2007

Subversion Server as Xinetd Service

Subversion has emerged as a popular versioning system. The subversion package ships with almost all Redhat flavours of Linux . The subversion server is run using the binary "svnserve" with appropriate arguments. I will mention a few of them here.

-r Directory : Specifies the root/base directory for all repositories.
-d : Run the server in daemon mode
-i : Run the server in inetd mode


What I usually do was to run "svnserve" in the daemon mode with a root directory specified, as follows:

[root@LinuxBox1 ~]#svnserve -r /home/repository -d

This will run as a standalone process all the time . This server is not accessed regularly, usually it is accessed only at the morning and evening of working days, when developers checkout and commit their projects. But svnserve is sitting there all the time consuming my valuable system resources. Another problem with this daemon mode is that I have to run the above command every time the machine restart, or have to put it in a start up script.


So I thought about a better alternative, to run it under xinetd service. The good thing about xinetd is that it will invoke svnserve only when necessary, thus consuming least system resources required, and I don't have to write separate start up script for svnserve.

All that is required to do is create a service file for svn(Even though the binary is svnserve, the service and subversion generally is called svn).

[root@LinuxBox1 ~]# vi /etc/xinetd.d/svn
#Subversion Server
#http://subversion.tigris.org/


service svn
{
socket_type = stream
wait = no
user = root
server = /usr/bin/svnserve
server_args = -r /home/repository -i
disable = no
}

# : Comments

socket_type : On what type of socket the service should listen. TCP(stream), UDP (dgram)

wait : How the server treats threads, a value of "yes" indicates that only a single connection will be managed by the service. If value is "no", a new server is started for each connection request.

user : The user identity under which the service will be started.

server : The binary used to start the service. To find out the path on your system, use:
[root@LinuxBox1 ~]#which svnserve
/usr/bin/svnserve

server_args : the arguments passed to the binary indicated by the option "server". Here, svnserve is run in inetd mode with /home/repository as the root

disable : Whether the service is enabled or disabled.

Save the file and restart the xinetd service.

[root@LinuxBox1 ~]#service xinetd restart

Svn by default listens on the port 3690. You can find out this in /etc/services.
[root@LinuxBox1 ~]#grep Subversion /etc/services
svn 3690/tcp # Subversion
svn 3690/udp # Subversion


Now to make sure that xinetd has invoked svnserve, check whether xinetd is listening on port 3690

[root@LinuxBox1 ~]# netstat -anp|grep 3690
tcp 0 0 0.0.0.0:3690 0.0.0.0:* LISTEN 30254/xinetd

As a final step to make sure that everything is working fine, checkout a project in this repository from another machine

[safeer@LinuxBox2 ~]$svn checkout --username safeer svn://linuxbox1/project1
Authentication realm: <svn://linuxbox1:3690
> Project 01 Repository
Password for 'safeer':
Checked out revision 0.

Thursday, March 15, 2007

MySQL user options file

The normal way to connect to a mysql server is to use the command line client 'mysql' as follows

[safeer@LinuxBox1 ~]$mysql -u safeer -h server01 -p app1
Enter password:

This will connect to the database 'app1' in server 'server01' using the username safeer, and a password.

There are different mysql clients used for different purposes, like mysqldump for backing up databases, mysqladmin for administrative tasks etc. For each of these clients you should specify the username, password,host and many other options.

If you are using the same values for these options frequently, you can get rid of typing the long statement by using mysql user options file. This file will be having the name .my.cnf and will be located in the users home directory.

Actually there are three Global option files for mysql viz,
/etc/my.cnf --- Global Options

$MYSQL_HOME/my.cnf --- Server Specific Options
$MYSQL_HOME will usually be /var/lib/mysql/. my.cnf will not be present here always.

Defaults-Extra-File - File specified with the option --defaults-extra-file=path
This need not have to be present at all.

User specific options will be present in the home directory of the user
~/.my.cnf

In addition, options can be specified at command line when using the clients.

If the same option appears in more than one place in the above mentioned list, the last one will get precedence over others.

Following contents are permitted in option files

Comments : Comments can be inserted with "#" and ";" at the begining

[group] : Program or program group that interact with mysql server. This can be the command line tools like mysql,mysqldump,mysqladmin,mysql,mysqld_safe etc....To represent all the command line client together (except mysqld) you can use [client]

Syntax for option file is the same as the command line options, except that the leading double dashes are removed

option : same as --option on command line

option=value : same as --option=value

For example, to connect to a database "app2" in the machine "server01" using the username "nebu" and password "my_pass123" using command line, also the communication between server and client should be compressed (if both end supports compression).

[safeer@LinuxBox1 ~]$mysql --compress --user="nebu" --password="my_pass123" --database="app2" --host="server01"

instead we can set this in user option file
/home/safeer/.my.cnf

[mysql]
compress
user="nebu"
password="my_pass123"
database="app2"
host="server01"


Now you can simply use 'mysql' without all those long options.
[safeer@LinuxBox1 ~]$mysql
This will achieve the same task as the previous command.

you can override any of the above options from command line. Suppose that you want to connect to another database "db_app3" on the same server, use:
[safeer@LinuxBox1 ~]$mysql --database="db_app3"

If you are using the same credentials for all clients you can put it under the [client] group. We can override those setting or add addition settings by including more [group] options

/home/safeer/.my.cnf

[client]
user="nebu"
password="my_pass123"

[mysqldump]
compact


You should make sure that only you have the permision to read and write to the options file

This setting will allow all clients to use the username "nebu" and password "my_pass123" (unless overridden at command line). In addition mysqldump will use the compact option.

I found the option file most useful when I had to use mysql clients with scripts, especially to take backups of databases. since there is no way for user interaction, I created database users with read permission to the databases to be backed up, put its username and password in the options file, and run mysqldump from a cronjob.