How many times have you written scripts and a had bad time with those having spaces? The remedy to this situation is your IFS value.
IFS or Internal Field Seperator holds the value which seperates the various entities. This can be file names, values read into a script by read etc. It is the character or characters designated as whitespace by the operating system.
The IFS is set to the newline and space character. The global variable $IFS stores the value. To view the exact value stored in IFS execute:
echo "$IFS" | cat -vTE ^I$ $
Running echo “$IFS” will not give you any visible output (after all, you are going to see a space and a newline). cat -vTE displays non printable characters , tabs as ^I and ends each line with a $ sign.
In a script which utilises filenames (with spaces), it is always preferable to change the IFS to include only the newline character opposed to the default space and newline character. Lets check out one such script which accepts filenames wih spaces. This scripts simply prints the file names in your current directory. (Remember to create some files in your currenct directory which has spaces. You may try the same script removing the lines with the IFS variable in reference to see the difference)
#!/bin/bash OIFS=$IFS # Original IFS IFS=$(echo -en "\n\b") # New IFS for fil in $(ls -1 $PWD); do echo $fil done IFS=$OIFS # Restore earlier IFS
IFS can also be used to read files with lines sepearated by a special character. For example in the /etc/passwd, to store the various entries like username, homedirectory etc.
The following script uses the while construct to determine the users who have the shell portion as /bin/false
#!/bin/bash
OIFS=$IFS
IFS=':'
while read username password userid groupid comments homedir shell_avail
do
if [[ $shell_avail == /bin/false ]]; then
echo "$username has no shell"
fi
done < /etc/passwd
IFS=$OIFS
In the above script each of the 7 portions of the /etc/passwd file is assigned to the 7 variables
username password userid groupid comments homedir shell_avail with the read command. The if portion in the script compares the seventh variable – shell_avail to /bin/false to determine the username and outputs it.
From now on you can use the IFS variable for all those files with spaces and extracting values separated by a special character.
Continue ReadingWe create RPM’s from the Source for a package. As an initial step, compile and install the source using normal procedures just to confirm all necessary libraries/dependencies are met.
Here I am explaining the whole process to create an RPM for CSF that could be installed on cPanel servers.
Getting ready with the Source Files:
Download Latest CSF from here : http://www.configserver.com/free/csf.tgz
Extract the tarball.
[root@server new]# tar -xvf csf.tgz [root@server new]# ls csf csf.tgz
Install to check all libraries/dependencies are met.
[root@server csf]# cd csf [root@server csf]# sh install.cpanel.sh *WARNING* TESTING mode is enabled - do not forget to disable it in the configuration Installation Completed
We confirmed all libraries/dependencies are met for installing CSF. We need to rename the tarball to define a version so that it could be used in the SPEC file.
[root@server csf]# cd .. [root@server new]# ls csf csf.tgz [root@server new]#mv csf csf-0.0.1 [root@server new]# tar -cvf csf-0.0.1.tar.gz csf-0.0.1
0.0.1 defines the version. (Can assign any). Now we are ready with the source file for CSF csf-0.0.1.tar.gz that could be used to generate RPM.
Building the RPM:
Install RPMBUILD tool:
[root@server ~]# yum install rpm-build
We never build RPM’s as ‘root’ users, but as normal users, because root can alter any file on the system, it was easy to inadvertently alter a running system by adding extraneous files or removing important files during interim builds of an RPM. Earlier RPM’s were build as root user but recently the RPM system changed to allow any user to build RPMs in a home directory. Building an RPM without the privileges of root prevents changes to core system files and hence we are on the safer side.
Initial Set-up:
We need to create a directory hierarchy for the rpm build tool to work with. To begin with, create a directory under your home directory which will act as the root directory for the build process. Lets make a directory ‘csfrpm’ under home directory for this purpose.
[sage@server ~]$ mkdir -p /home/your_username/csfrpm
[sage@server ~]$ cd /home/your_username/csfrpm
Create Five sub-directories under csfrpm.
[sage@server csfrpm]$ mkdir BUILD RPMS SOURCES SPECS SRPMS
[sage@server csfrpm]$ ls BUILD RPMS SOURCES SPECS SRPMS
Copy the source code that we have created(csf-0.0.1.tar.gz) to the SOURCES folder. Make sure that the owner for source file is your_username.
[sage@server ~]$ cp csf-0.0.1.tar.gz /home/your_username/csfrpm/SOURCES/
Create the SPEC file:
SPEC file is noting but the configuration for rpmbuild tool.
[sage@server csfrpm]$ vi SPECS/csf.spec
# This is a sample spec file for csf
%define _topdir /home/your_username/csfrpm
%define name csf
%define release 0
%define version 0.0.1
BuildRoot: %{_tmppath}/%{name}-%{version}-root
Summary: GNU csf
License: GPL
Name: %{name}
Version: %{version}
Release: %{release}
Source: %{name}-%{version}.tar.gz
Group: Security/Tools
%description
A Stateful Packet Inspection (SPI) firewall, Login/Intrusion Detection and Security application for Linux servers.
%prep
%setup -q
%install
./install.cpanel.sh prefix=$RPM_BUILD_ROOT/usr/local
%clean
%{__rm} -rf %{buildroot}
%files
%defattr(-,root,root,0755)
Finally Build the RPM:
[sage@server csfrpm]$ rpmbuild -v -bb --clean SPECS/csf.spec
You can see the result if everything went fine:
Processing files: csf-0.0.1-0 Checking for unpackaged file(s): /usr/lib/rpm/check-files /var/tmp/csf-0.0.1-root Wrote: /home/your_username/csfrpm/RPMS/i386/csf-0.0.1-0.i386.rpm Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.84469 + umask 022 + cd /home/your_username/csfrpm/BUILD + cd csf-0.0.1 + /bin/rm -rf /var/tmp/csf-0.0.1-root + exit 0 Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.84469 + umask 022 + cd /home/yuor_username/csfrpm/BUILD + rm -rf csf-0.0.1 + exit 0
The RPM is written to /home/your_username/csfrpm/RPMS/i386/csf-0.0.1-0.i386.rpm
Continue ReadingPostgreSQL or Postgres is an object-relational database management system (ORDBMS). Unlike MySQL, PostgreSQL is not controlled by any single company, it is a community developed project. It is a advanced version of the ‘Ingres’ Database project (which is how the project gets the name post-ingres or postgres ).
Postgres is one of the best open-source database alternative which is fully object oriented and transactions compliant. It has stored procedures, multiple views and a huge set of datatypes. Some of the other notable features are as follows.
Objects and Inheritance
Database consists of objects and the database administrators can design custom or user-defined objects for the tables. Inheritance is another feature. Tables can be set to inherit their characteristics from a “parent” table.
Functions
Functions can be used in Postgres. These can be written in the postgres’ own procedural language called ‘PL/pgSQL’ which resembles Oracle’s procedural language ‘PL/SQL’ or any other common scripting languages which support posgtres’ procedural language like PL/Perl, plPHP, PL/Python, PL/Ruby etc. Run the following in the psql client to determine if functions is enabled:
SELECT true FROM pg_catalog.pg_language WHERE lanname = 'plpgsql';
To create user-defined functions we use the CREATE OR REPLACE FUNCTION command. Example:
CREATE OR REPLACE FUNCTION fib ( fib_for integer ) RETURNS integer AS $$ BEGIN IF fib_for < 2 THEN RETURN fib_for; END IF; RETURN fib(fib_for - 2) + fib(fib_for - 1); END; $$ LANGUAGE plpgsql;
Indexes
An index is like a summary of a certain portion of the table. It is an optimization technique which increases speed of accessing records from a database. PostgreSQL supports indexes like Btree, hash etc. User-defined index methods can also be created. Indexes are created on tables with respect to a particular field (based on which there are a number of queries). As an example for a table:
CREATE TABLE name ( id integer, fname varchar lname varchar );
To create an index on table name with respective to the field id (as there are many queries on this table requesting for firstname or lastname from the id provided), we use the index:
CREATE INDEX name_id_index ON name (id);
Triggers
Triggers are events or functions run upon the action of certain SQL statements which modify data in some records. Depending on the kind of modification we can have multiple triggers in a database. Postgres supports multiple triggers written in PL/PgSQL or it’s scripting counterparts like PL/Python. The trigger function must be defined before the trigger can be created. The trigger function must be declared as a function taking no arguments and returning type trigger. CREATE TRIGGER command is used to declare triggers.
Concurrency
PostgreSQL ensures concurrency with the help of MVCC (Multi-Version Concurrency Control), which gives the database user a “snapshot” of the database, allowing changes to be made without being visible to other users until a transaction is committed.
PostgreSQL’s MVCC keeps all of the versions of the data together in the same partition in the same table. By identifying which rows were added by which transactions, which rows were deleted by which transactions, and which transactions have actually committed, it becomes a straightforward check to see which rows are visible for which transactions.
Inorder to accomplish this, Rows of a table are stored in PostgreSQL as a tuple. Two fields of each tuple are xmin and xmax. Xmin is the transaction ID of the transaction that created the tuple. Xmax is the transaction ID of the transaction that deleted it (if any).
Along with the tuples in each table, a record of each transaction and its current state (in progress, committed, aborted) is kept in a universal transaction log.
When data in a table is selected, only those rows that are created and not destroyed are seen. That is, each row’s xmin is observed. If the xmin is a transaction that is in progress or aborted, then the row is invisible. If the xmin is a transaction that has committed, then the xmax is observed. If the xmax is a transaction that is in progress or aborted and not the current transaction, or if there is no xmax at all, then the row is seen. Otherwise, the row is considered as already deleted.
Insertions are straightforward. The transaction that inserts the tuple simply creates it with the xmax blank and the xmin set to its transaction ID. Deletions are also straightforward. The tuple’s xmax is set to the current transaction. Updates are no more than a concurrent insert and delete.
Views
A view is a table which does not exist in the database. It is a virtual table created from fields in various tables and is joined together based on some criteria. Views can be used in place of tables and will accomplish the task same as that of a table. The CREATE VIEW statement is used to accomplish this eg:
CREATE VIEW best_sellers AS SELECT * FROM publishers WHERE demand LIKE 'high';
Foreign Keys
The primary key used in one table which is used to refer to the records in a second table is called the foreign key of the second table.
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);
CREATE TABLE orders (
order_id integer PRIMARY KEY,
product_no integer REFERENCES products (product_no),
quantity integer
);
Here product_no is the foreign key in the second table created. The foreign key field may have values which are repeated unlike primary keys.
Files Users and Configuration
The main configuration file of Postgres is postgresql.conf. This can be located in the ‘data’ directory. It may be present either in /var/lib (/var/lib/pgsql/data/postgresql.conf) or /usr/local (/usr/local/pgsql/data/postgresql.conf). Temporary changes to the configurations can be made using postmaster command.
The init script that starts the postgres service is /etc/init.d/postgresql . It runs a number of child processes concurrently. The postgres server process is postmaster. These processes and files associated with PosgreSQL are owned by the user/group postgres. The default port used for database connections is 5432
The user postgres is the PostgreSQL database superuser. We can create a number of super users for the database (this accomplished by the create role command ), however, the default super user is postgres. The postgres user has the privilege to access all the databases and files in the server (Unless the user root is created in postgres as a superuser).
Client Authentication is controlled by the file pg_hba.conf in the data directory, e.g., /var/lib/pgsql/data/pg_hba.conf. (HBA stands for host-based authentication.)
Each record specifies a connection type, a client IP address range (if relevant for the connection type), a database name or names, and the authentication method to be used for connections matching these parameters.A record is typically in one of two forms:
local database authentication-method [ authentication-option ]
host database IP-address IP-mask authentication-method [ authentication-option ]
local : This record pertains to connection attempts over Unix domain sockets.
host : This record pertains to connection attempts over TCP/IP networks.
database : Specifies the database that this record applies to. The value all specifies that it applies to all databases, while the value sameuser identifies the database with the same name as the connecting user.
authentication methods
trust: The connection is allowed unconditionally.
reject: The connection is rejected unconditionally.
password: The client is required to supply a password which is required to match the database password that was set up for the user.
md5: Like the password method, but the password is sent over the wire encrypted using a simple challenge-response protocol.
ident: This method uses the “Identification Protocol” as described in RFC 1413. It may be used to authenticate TCP/IP or Unix domain socket connections, but its reccomended use is for local connections only and not remote connections.
Front-ends
The minimalistic front-end for PostgreSQL is the psql command-line. It can be used to enter SQL queries directly, or execute them from a file. phpPgAdmin is a web-portal used for PostgreSQL administration written in PHP and based on the popular phpMyAdmin. Likewise pgAdmin is a graphical front-end administration tool for PostgreSQL, which has support on multiple platforms. The latest stable version of the same is pgAdmin III.
Some administration related commands
Command to login to psql database mydb as user myuser:
psql -d mydb -U myuser
Command to login to psql database mydb as user myuser on a different host myhost:
psql -h myhost -d mydb -U myuser
If the port the server runs is different we use -p [port number] . Upon entering the psql shell the prompt will show the database name currently being used. In the above example it will show
mydb=> (if logged in as an ordinary user )
mydb=# (if logged in as a super user like postgres)
Create a PostgreSQL user
There are two ways to create a postgres database user. The only user initially allowed to create users is postgres. So one has to switch to this user before creating other users with varying privileges.
1. Creating the user in the shell prompt, with createuser command.
switch to the postgres user with:
su - postgres createuser tom Shall the new role be a superuser? (y/n) n Shall the new role be allowed to create databases? (y/n) y Shall the new role be allowed to create more new roles? (y/n) n
2. Creating the user in the PSQL prompt, with CREATE USER command.
switch to the postgres user with:
su - postgres create user mary with password 'marypass';
Creating and deleting a PostgreSQL Database
There are two way to create databases.
1. Creating database in the PSQL prompt, with createuser command.
CREATE DATABASE db1 WITH OWNER tom;
2. Creating database in the shell prompt, with createdb command.
createdb db2 -O mary
To delete an entire database from within the psql prompt do :
DROP DATABASE db1;
Determining execution time of a query
Turn on timing with
\timing
Now execute the qery:
SELECT * from db1.employees ; Time: 0.065 ms
Calculate postgreSQL database size in disk
SELECT pg_database_size('db1');
to get the values in human readable format
SELECT pg_size_pretty(pg_database_size('db1'));
to calculate postgreSQL table size in disk
SELECT pg_size_pretty(pg_total_relation_size(‘big_table’));
Slash commands used in psql
To list all slash commands and thier purpose. Login to psql and issue to the command \? . Some of the most commonly used slash commands are the following:
| List databases | \l |
| System tables | \dS |
| Types | \dT |
| Functions | \df |
| Operators | \do |
| Aggregates | \da |
| Users | \du |
| Quit from psql | \q |
| Connect to different database db2 | \c db2 |
| Describe Table/index/view/sequence | \d |
The below can be used with a specific table/index/view name for description of the specific table/index/view
| Tables | \dt |
| Indexes | \di |
| Sequences | \ds |
| Views | \dv |
Useful Bash commands
Bash command to list all the postgresql databases:
psql -l #This can be run as a unix user who is also a super user in postgresql
Indirect bash command to list all the postgresl users:
psql -c '\du' #-c is used to run an internal or sql command in psql shell
Backing up and restoring databases
To dump the database to an sql file use the bash command:
pg_dump mydb > db.out
To restore a database from an sql backup file (via bash)
psql -d newdb -f backupdb.out or psql -f backupdb.out newdb
(here the database newdb must be already created and the file backupdb.out must be present in the current directory)
To take the backup of all the Postgres databases in the server:
pg_dumpall > /var/lib/pgsql/backups/dumpall.sql
(Only possible with the postgres or the database superuser )
Resetting database user’s password
To change the password for a database user (say ‘thomas’):
ALTER USER thomas WITH PASSWORD 'newpassword';
This same command can be used to reset the password for the postgresql super user postgres, but in this case, you will have to enable password less login for postgres user by adding the following line to the top of the file pg_hba.conf in the data directory of postgres. Once the password is reset this line can be removed:
local all postgres trust
Next we issue the same command but for the user postgres
ALTER USER postgres WITH PASSWORD 'newpassword';
To create a super user via bash with multiple roles
createuser -sPE mysuperuser
Instead of this we can also use the below psql shell command:
CREATE ROLE mysuperuser2 WITH SUPERUSER CREATEDB CREATEROLE LOGIN ENCRYPTED PASSWORD 'mysuperpass2';
Physical database files in postgres
The files in data/base are named by the oid (Object Identifier) of the database record in
pg_database, like this:
cd /var/lib/pgsql/data/base ls -l total 33 drwx------ 22 postgres postgres 4096 Jul 23 20:06 ./ drwx------ 11 postgres postgres 4096 Aug 1 05:59 ../ drwx------ 2 postgres postgres 4096 Jun 20 09:32 1/ drwx------ 2 postgres postgres 4096 Mar 3 13:36 10792/ drwx------ 2 postgres postgres 4096 Jun 20 15:09 10793/ drwx------ 2 postgres postgres 4096 May 27 01:40 16497/ drwx------ 2 postgres postgres 4096 May 27 01:40 16589/ drwx------ 2 postgres postgres 4096 Jun 20 10:28 16702/ drwx------ 2 postgres postgres 4096 May 27 01:40 16764/ drwx------ 2 postgres postgres 4096 May 27 01:40 16785/ drwx------ 2 postgres postgres 4096 Aug 1 04:37 16786/ drwx------ 2 postgres postgres 4096 Aug 1 04:36 19992/ drwx------ 2 postgres postgres 4096 May 27 01:40 19997/
To obtain the oid, execute the following command in psql prompt
postgres=# select oid,datname from pg_database order by oid; oid | datname ---------+-------------------------- 1 | template1 10792 | template0 10793 | postgres 16497 | gadgetwi_Unable 16589 | vimusicc_filehost 16702 | personea_altissimo 16764 | shopping_businessfinance 16785 | ansonyi_wp2 16786 | ansonyi_wp 19992 | globook_PostgreSQLContinue Reading
Kernel Recompilation
Compiling custom kernel has its own advantages and disadvantages. It helps to optimize the kernel to your environment (hardware and usage patterns). I shall try to guide you through Kernel recompilation process.
Step 1:
Download the kernel source
cd /usr/local/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-x.y.z.tar.bz2
Note: Replace x.y.z with actual version number.
Step 2:
Extract the source file
tar -xjvf linux-x.y.z.tar.bz2
Step 3:
Patching the Kernel
If you are requested to apply any patches , follow these steps
a) Move the downloaded kernel patch to the /usr/local/src directory.
b) Extract the patch file
c) Patch the kernel source using the extracted patch file
cd /usr/local/src/linux-x.y.z
patch -p1 < patchfile-2.2.x
Now the Kernel Source is patched against known vulnerabilities.
Step 4:
Configuration
If you are trying to upgrade the Kernel of already running server , it is always better use the existing configuration. To do this follow these steps
#uname -a
Linux Server1 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
# cd /boot
There you can see different configuration files as given below
#ls
config-2.6.18-128.el5 initrd-2.6.18-128.el5.img message
config-2.6.18-164.el5 initrd-2.6.18-164.el5.img quota.user*
identify the configuration file corresponding to the version of OS installed , In our case it is config-2.6.18-164.el5 . We are copying this file to the downloaded kernel source to use it during configuration.
#cp -p config-2.6.18-164.el5 /usr/local/src/linux-x.y.z/.config
# make clean
# make mrproper
# make menuconfig
You have to select different options as per your need. If you intended to use the existing configuration ,specify the path to the file ( .config in this case) by selecting the option
“Load an Alternative configuration file”
Step 5: Compilation
Compile the Kernel using the following commands
Compile to create a compressed kernel image
# make
Compile kernel modules:
# make modules
Install kernel modules
# make modules_install
Step 6: Install Kernel
If the above steps completed without any errors , now its the time to Install the new Kernel
# make install
It will install three files into /boot directory as well as modification to your kernel grub configuration file:
System.map-x.y.z
config-x.y.z
vmlinuz-x.y.z
Step 7: Create the Initrd image
Type the following command :
# cd /boot
# mkinitrd -o initrd.img-x.y.x x.y.z
initrd images contains device driver which needed to load rest of the operating system later on. Not all computer requires it, but it is better to create one
Step 8: Boot Loader Modification
Mofdify the boot loader to boot the new OS as default . Check the documentaions corresponding to your boot loader
Step 9: The last step
execute the following command
#reboot
Wait a few minutes and once it is up , you can see that the new Kernel is loaded
Before trying to enable iptable modules on the VPS, make sure that those modules are enabled on the root node server. To check whether the particular iptable modules are enabled or not on the root node, execute the following command.
lsmod
A Sample out put for the lsmod is :
Module Size Used by
xt_helper 35584 0
ip_conntrack_ftp 42320 2
ipt_LOG 39808 0
ipt_owner 34944 0
ipt_REDIRECT 34944 0
ipt_recent 43404 2
xt_state 35200 5
sch_sfq 38912 1
cls_u32 41352 1
sch_cbq 50688 1
ppp_deflate 39168 0
zlib_deflate 52760 1 ppp_deflate
ppp_async 45184 0
ppp_generic 62624 2 ppp_deflate,ppp_async
slhc 39552 1 ppp_generic
crc_ccitt 35200 1 ppp_async
tun 47872 0
vzethdev 47264 0
simfs 38296 36
vzrst 173096 0
vzcpt 148792 0
vzdquota 78832 36 [permanent]
xt_tcpudp 36224 21
xt_length 34944 0
ipt_ttl 34816 0
xt_tcpmss 35328 0
ipt_TCPMSS 37248 0
iptable_mangle 37888 36
xt_multiport 36224 0
xt_limit 36352 4
ipt_tos 34560 0
ipt_REJECT 39556 1
iptable_nat 43532 46
ip_nat 53392 3 ipt_REDIRECT,vzrst,iptable_nat
iptable_filter 37760 42
ip_conntrack 100884 29 xt_helper,ip_conntrack_ftp,xt_state,vzrst,vzcpt,iptable_nat,ip_nat
nfnetlink 40392 2 ip_nat,ip_conntrack
ip_tables 57440 3 iptable_mangle,iptable_nat,iptable_filter
x_tables 52744 17 xt_helper,ipt_LOG,ipt_owner,ipt_REDIRECT,ipt_recent,xt_state,xt_tcpudp,xt_length,ipt_ttl,xt_tcpmss,ipt_TCPMSS,xt_multiport,xt_limit,ipt_tos,ipt_REJECT,iptable_nat,ip_tables
autofs4 57480 2
hidp 83584 2
rfcomm 105000 0
Here we can see most of the modules are already enabled on the node server. If not enabled, execute the following commands one by one to enable those.
modprobe ipt_helper
modprobe ipt_REDIRECT
modprobe ipt_state
modprobe ipt_TCPMSS
modprobe ipt_LOG
modprobe ipt_TOS
modprobe iptable_nat
modprobe ipt_length
modprobe ipt_tcpmss
modprobe iptable_mangle
modprobe ipt_limit
modprobe ipt_tos
modprobe iptable_filter
modprobe ipt_helper
modprobe ipt_tos
modprobe ipt_ttl
modprobe ipt_REJECT
modprobe ipt_helper
modprobe ipt_owner
Next step is to enable these modules on the VPS.
Stop the container first : vzctl stop 960 ( replace 960 with the concerned VPS ID )
Execute the following command :
vzctl set 960 –iptables ipt_REJECT –iptables ipt_tos –iptables ipt_TOS –iptables ipt_LOG –iptables ip_conntrack –iptables ipt_limit –iptables ipt_multiport –iptables iptable_filter –iptables iptable_mangle –iptables ipt_TCPMSS –iptables ipt_tcpmss –iptables ipt_ttl –iptables ipt_length –iptables ipt_state –iptables iptable_nat –iptables ip_nat_ftp –iptables ip_conntrack_ftp –iptables ip_conntrack_irc –iptables ip_nat_irc –iptables ipt_owner –iptables ipt_helper –save
Start the container : vzctl start 960
check whether the modules are enabled from the configuration file cat /etc/vz/conf/960.conf. You are DONE.
Please note that if the command “vzctl set 960 –iptables ipt_ ….” is executed for the second time for the same VPS, it will over write the previous configuration.
For enabling it on all VPSes, please add to /etc/sysconfig/vz all those modules like IPTABLES=”module1 module2 ….etc”
Continue Reading