Wednesday, March 28, 2007
Linux user management
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
-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
[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.
Apache HTTP Authentication
With apache http authentication, you can password protect either part of
or an entire website. Thus you can allow only a selected set of people
to view parts of your website.
The configuration directives required for this can be put either in apche server configuration files ( /etc/httpd/conf/httpd.conf OR /etc/httpd/conf.d/*.conf ) under the directory directive or in a per directroy user access file (.htaccess). If you are using .htaccess file, your main configuration should have the following directive in it:
AllowOverride AuthConfig
First
of alll, we need to create a password database file containing the
username password pair. The password is encrypted by default using CRYPT
encryption. This is a kind of irreversible encryption.
The command used to create password file is htpasswd which comes with apache package
[root@LinuxBox1 ~]#htpasswd -c /var/hosting/safeer/secrets/users.sec safeer
New password:
Re-type new password:
Adding password for user safeer
This command does 2 things. The '-c' option creates a new password file /var/hosting/safeer/secrets/users.sec if it does not exist or erases its contents if already exists. Then the user 'safeer' is added to the file.
[root@LinuxBox1 ~]#cat /var/hosting/safeer/secrets/users.sec
safeer:zgmIJyIiuD87U
To add a new user to the file
[root@LinuxBox1 ~]#htpasswd /var/hosting/safeer/secrets/users.sec rojar
New password:
Re-type new password:
Adding password for user rojar
[root@LinuxBox1 ~]#cat /var/hosting/safeer/secrets/users.sec
safeer:zgmIJyIiuD87U
rojar:NQ7DlFlAqSMBQ
To delere a user from the file
[root@LinuxBox1 ~]#htpasswd -D /var/hosting/safeer/secrets/users.sec safeer
Deleting password for user safeer
My document root is /var/hosting/safeer/www and I want to password protect a subdirectory /var/hosting/safeer/www/confidential.
If you are modifying the main configuration files, the entries whould go inside <Diretory /var/hosting/safeer/www/confidential></Directory> . If you are using .htaccess place that file in /var/hosting/safeer/www/confidential. If you are editing the main configuration files, dont forget to restart the service.
Now either in the main configuration files or .htaccess file add the following.
AuthType Basic
AuthName "Confidential Data"
AuthUserFile /var/hosting/safeer/secrets/users.sec
Require user rojar
AuthType
: Type of authentication. Most common form is 'Basic'. Password is sent
in cleartext. Another methode supported is 'Digest' and uses SHA or MD5
algorithms. This is very secure methode, but only recent versions of
http clients support this type of authentication.
AuthName
: Authentication Ream. This information will be displayed to client as
part of the pop window that prompts for username and password. In
addition the client will automatically use the same credentials if two
or more restricted areas are sharing the same realm. Once entered
his/her credentials, the user will not be prompted for username and
passwrod repeatedly for different areas if they are using the same
realm.
AuthUserFile : Location of the password file. The file should not be inside the document root.
Require : Specifies who have acces to the area (authorization). Here only the user rojar has the privilege to access this area.
If you want to allow more than one user to allow access to a particular area:
Require user safeer baiju nebu rojar ...
will allow all these users provided they all have corresponding entries in the 'AuthUserFile'
The easiest way is to allow all the users in the AuthUserFile:
Require valid-user
You can use groups to organise users for authorization. The directive:
AuthGroupFile /var/hosting/safeer/secrets/groups.sec
The group file can contain a number of group names and its members in the following format:
Groupname: user1 user2 user3 ....
Eg:
/var/hosting/safeer/secrets/groups.sec
Confidential: safeer rojar
Now modify the Require directive to include this group for authorization:
Require group Confidential
This will let users listed in Confidential group to access this area. Altogether the directives reauired are:
AuthType Basic
AuthName "Confidential Data"
AuthUserFile /var/hosting/safeer/secrets/users.sec
AuthGroupFile /var/hosting/safeer/secrets/groups.sec
Require group Confidential
Wednesday, March 14, 2007
File sharing with NFS
Setting up an NFS server
Make sure that nfs and portmap services are running.
[root@LinuxBox1 ~]#service nfs start
[root@LinuxBox1 ~]#service portmap start
The main configuration file for NFS is /etc/exports
In this file we will specify which directories should be shared for access from network along with a number of security and performance options. Each line of the file will list a folder to be shared and the details of how it is shared.
The syntax of the file is as follows:
directory machineX(optionA,optionB,.) machineY(optionC,optionD,..) . .
directory : The directory you want to share. All files and directories below this and is in the same file system will be automatically available.
machine : client machines that can access the directory via NFS. This can be either hostname, IP address or network.
Wild cards * and ? can be used in domain names. While a single '*' alone will indicate 'all machines', it is a little bit different with fully qualified domain names. *.example.com can substitute abc.example.com, xyz.example.com etc...but cant substitute pqr.abc.example.com. For this to work you will have to specify *.*.example.com. To represent sub1.example.com, sub2.example.com etc.. we can use sub?.example.com.
We can specify a whole network by using netmasks; for example, 192.168.0.0/25 allows hosts from 192.168.0.1 to 192.168.0.126 to access the share. Alternatively you can use 192.168.0.0/255.255.255.128
options : Options indicates what kind of access privileges are applicable for that particular client. Following is a list of most common options.
ro : Read Only- remote clients cant change the files in the share. (default)
rw : Read Write - clients and both read and write files in the share
sync : Writes the changes to the disk first and then only answers the access request . (default)
async : Allows access request to the share before the changes are written to the disk. This can cause undefined behaviours if the server is shutdown/stopped uncleanly.
root_squash: Prevents the client machine root user from having root privilege on the share. Instead the root user is mapped to user 'nfsnobdy' on the server. Generally this user will have a UID 65534. (default)
no_root_squash : turn off root squashing.
When NFS service is started, /etc/exports file is read by the command /usr/sbin/exportfs and passes the control to RPC services. When this file is changed, it is necessary to re-read it. This can be done by restarting or reloading the nfs service, or using the exportfs command.
[root@LinuxBox1 ~]#service nfs restart
OR
[root@LinuxBox1 ~]#service nfs reload
OR
[root@LinuxBox1 ~]#exporfs -r
of these three, exportfs -r is preferred.
Example:
/etc/exports
/fc5 *
/home/public 192.168.0.5(rw,sync)
/fedora/pub 192.168.0.0/24(rw,sync)
[root@LinuxBox1 ~]#exportfs -r
To list the exported directories
[root@LinuxBox1 ~]#exportfs
/home/public 192.168.0.5
/fedora/pub 192.168.0.0/24
/fc5
OR
[root@LinuxBox1 ~]#showmount -e
Export list for linuxbox1:
/fc5 *
/fedora/pub 192.168.0.0/24
/home/public 192.168.0.5
To view the nfs shares of a remote machine 'linuxbox3'
[root@LinuxBox1 ~]#showmount -e linuxbox3
Export list for linuxbox3:
/home/pub linuxbox1.linuxvalley.com
Setting up an NFS client
Mounting remote NFS shares- use mount command with the following syntax
mount [-o option1,[option2],.....] server:/path/to remote/share /path/to/local/mountpoint
[root@LinuxBox2 ~]#mount -o ro linuxbox1:/fedora/pub /mnt/remote1
[root@LinuxBox2 ~]#mount|grep /fedora/pub
linuxbox1:/fedora/pub on /mnt/remote1 type nfs (ro,addr=192.168.0.101)
To mount this share at boot time, edit /etc/fstab
#device/share mountpoint filesystem mount-options dump fsckorder
linuxbox1:/fedora/pub /mnt/remote1 nfs rw,soft 0 0
[root@LinuxBox2 ~]#mount -a
Common mount options applicable for nfs shares
hard/soft : if an nfs file/server is unavailable temporarily whether the client should stop and wait for the serer to come back online (hard) or report error (soft). The hard option will cause your client program to hang if the server is unavailable for long time. Soft is preferred normally.
intr : NFS requests can be interrupted (usually by pressing Ctrl+C). This option is recommended to be used with hard .
noexec : Binaries can't be executed on mounted filesystem.
nosuid : Disable SUID and SGID bits
rsize=NUM and wsize=NUM : Speed up NFS communication by reading(rwize) and writing(wsize) large data blocks
Now we can access the nfs share /fedora/pub on linuxbox1 through the local directory /mnt/remote1.