Tuesday, June 22, 2010

building a secure web server with centos-5

SkyHi @ Tuesday, June 22, 2010

Part 1 | Part 2 | Part 3 | Troubleshooting


Introduction

This is an updated version of my original LAMP (Linux Apache MySQL and Perl/PHP) guide that was based on CentOS 4. Now updated and tweaked for CentOS 5, I will take you through the steps required to build a secure Linux web server (LAMP) on CentOS 5.


I have a background working for an ISP, so I’ve based this build on the same configuration many hosting providers use. It supports virtual hosts (multiple websites), secure FTP access, locked down SSH access, and a sensible directory structure.


If you follow this guide, you will get a web server up and running within a couple of hours depending on whether you follow it step by step, or prefer to experiment first. If you are new to Linux then give it a try and learn something new, you never know you may surprise yourself!


Good luck!



A word on web hosting


Before you get started with your server build, I’d like to talk about where you are going to host this server. There have been a number of developments in the past few years in regards to people hosting websites on their home ISP broadband connection.


Firstly, did you know that many of the major search engines will not crawl your website if it’s hosted on a residential IP address? What I mean by residential is an IP address provided by the likes of an ADSL or broadband provider (e.g. Virgin Media, BT, PlusNet, here in the UK). It will depend on the ISP whether you get a ‘fixed’ IP address or not, and even if you do your site will simply be ignored by the major search engines as they will recognise the IP address in a residential (non ISP) range. Don’t get me wrong, running web servers at home is great fun but I would recommend you avoid it unless it is purely for testing.


So, where is the best place to host your shiny new CentOS web server?


I would highly recommend getting a VPS (Virtual Private Server). There are plenty of hosting companies offering Virtual Private Servers, and VPS hosting is getting cheaper.


I would personally recommend Linode, I have been using them since 2006 and recently they have started hosting virtual servers in the London, UK as well as the USA. They provide a generous amount of bandwidth, starting at around 200GiB per month with 16GB+ of disk space depending on which option you go for. You can choose from a massive list of Linux distro’s, including CentOS 5! They use Xen virtualisation and they have an excellent web interface for accessing your server stats, server controls, DNS, and console access.


Getting Started


CentOS 5 is completely free and developed by a team of core developers at a North American Enterprise Linux vendor. In turn the core developers are supported by an active user community including system administrators, network administrators, enterprise users, managers, core Linux contributors and Linux enthusiasts from around the world.


CentOS has numerous advantages over some of the other clone projects including: an active and growing user community, quickly rebuilt, tested, and QA’ed errata packages, an extensive mirror network, developers who are contactable and responsive, multiple free support avenues including IRC Chat, Mailing Lists, Forums, a dynamic FAQ. Commercial support is offered via a number of vendors.


CentOS 5 is distributed on six CD’s, all of which are available for download from the CentOS website.


Download phpMyAdmin


This is optional, but I would highly recommend this excellent web interface for administering your MySQL databases. I have used this in the past to provide customers with their own phpMyAdmin login username, so they can manage their databases easily.


http://www.phpmyadmin.net


Installing CentOS


NOTE: If you are using a virtual private server (VPS) provided by a hosting company such as Linode, and CentOS is already installed then skip ahead to the next section.


  • Insert CD of the CentOS 5 installation CD and boot your server.
  • At the installation menu, just press ENTER for the graphical installation wizard.
  • When prompted for an installation type select custom installation.
  • Use automatic partitioning for the disks.
  • Remove all partitions from system (make sure you are happy to wipe all existing data!!).
  • Boot Loader: Leave default settings.
  • Network Configuration: Configure this with an internal IP address and DNS name.
  • Firewall: Select ‘No firewall’ as this will be installed and configured later.
  • SELinux: Set to ‘Disabled’. This is still very experimental so I would leave this switched off unless you really know what you are doing.
  • Authentication: Set a secure root password using random characters and numbers (upper an lower case).
  • Package Selection: Choose minimal configuration (Other packages can be installed at a later stage according to the server role).

WARNING!! – The server should not be connected to the internet until the configuration is completed and secure!


Updating the System


Now that you have CentOS 5 installed, we need to make sure it’s up to date and then do some basic security configuration with SSH. Unlike CentOS 4, you no longer have to import the RPM key to update and install software. It does this for you.


To check for updates type the following:


# yum check-update


Now perform the update process. Note, the -y is to accept all updates which I recommend as it’s a clean installation.


# yum –y update


Setting the clock

I strongly advise that you setup the timezone and clock correctly. First, you set /etc/localtime to link to the correct timezone, then either set the time manually or configure NTPD to syncronise with an internet time server such as pool.ntp.org.


Example of setting the timezone to GMT:


# ln -sf /usr/share/zoneinfo/GMT /etc/localtime


Setting the hardware clock:


# vi /etc/sysconfig/clock


System Services Configuration


As this is going to be a finely tuned web server, we don’t want uneccessary daemons running! Firstly, lets list all the daemons that have been configured to run at startup.


# chkconfig –list|grep on


You should now get an output similar to the following:


anacron 0:off 1:off 2:off 3:off 4:off 5:off 6:off

atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off

crond 0:off 1:on 2:off 3:on 4:on 5:on 6:off

cups 0:off 1:on 2:off 3:on 4:on 5:on 6:off

haldaemon 0:off 1:on 2:off 3:off 4:on 5:on 6:off

messagebus0:off 1:on 2:off 3:off 4:on 5:on 6:off

network 0:off 1:on 2:off 3:off 4:on 5:on 6:off

syslog 0:off 1:on 2:off 3:off 4:on 5:on 6:off


Your list will probably be a lot longer as this is just an example, but what you can see here is the different run levels and their on/off status. Most daemons start at run level 3. Now lets switch off the daemons that aren’t needed. I’ve listed a few more here that you are likely to find.


# chkconfig cups off

# chkconfig apmd off

# chkconfig netfs off

# chkconfig pcmcia off

# chkconfig smartd off

# chkconfig anacron off

# chkconfig mdmonitor off

# chkconfig isdn off


NOTE: If you are using Linode then you should also switch off Kudzu (hardware detection) as this serves no purpose on a virtual UML system.


Host Access (TCP_WRAPPERS)


There are two host access files (/etc/hosts.allow and /etc/hosts.deny), that are part of the TCP_WRAPPER package. This makes it possible to allow or deny access to certain services based on the IP.


Edit the hosts.allow and hosts.deny files:

# vi /etc/hosts.allow


sshd:<IP ADDRESS>

vsftpd:ALL

sendmail:ALL


# vi /etc/hosts.deny


ALL:ALL


The <IP ADDRESS> above is the internet IP you are connecting from (don’t include < or >). You can enter multiple IP address here (separated by spaces) or to allow SSH from any IP just replace with ALL.


The root account should never be able to login via SSH (without first logging in as a user). You must change this, so edit /etc/ssh/sshd_config and ensure the following is set:


# vi /etc/ssh/sshd_config


Change the following lines as follows:


PermitRootLogin no

Protocol 2


Note: Some of these lines may already exist but will be commented out using #. To enable these commands the # needs to be removed.


Add Default Accounts


Before proceeding with any of the steps below, first create a user account that you will use to log in to this server. This account will be used for SSH connections.


# adduser <username>

# passwd <username>


You should now have access to the server via SSH. Download PuTTY and make sure it works.

Part 2: Configuring the Server


Configuring CentOS


  • Edit /etc/hosts and /etc/sysconfig/network with hostnames
  • Install Packages

Example of /etc/hosts:


# Do not remove the following line, or various programs

# that require network functionality will fail.

127.0.0.1 localhost

67.34.32.11 www.mydomain.com


Example of /etc/sysconfig/network


NETWORKING=yes

HOSTNAME=www.mydomain.com


Installing Packages


# yum -y install httpd openssl-devel openssl mod_ssl vsftpd rpm-build rpm-devel autoconf automake lynx gcc

# yum -y install mysql mod_auth_mysql mysql-devel mysql-server

# yum -y install mod_python python python-devel

# yum -y install perl mod_perl mod_perl-devel openssl-perl perl-Convert-ASN1 perl-Date-Calc perl-DateManip perl-HTML-Parser perl-libwww-perl perl-CPAN perl-DBD-MySQL perl-XML-Parser

# yum -y install php-devel php php-domxml php-gd php-mbstring php-mysql php-ncurses php-pear

# yum -y install webalizer

# yum -y install sendmail sendmail-cf




Creating Directory Structure


All websites will be held in /home/.sites/. The first site that needs to be created is the _default site, which will be used as this servers default website.


# mkdir /home/.sites

# cd /home/.sites

# mkdir _default

# cd _default

# mkdir logs private cgi-bin web

# cd web

# mkdir stats


Now change the ownership of these directories to adminftp as follows:


# cd /home/.sites

# chown adminftp _default -R


Configure the required system services sto start at boot:


# chkconfig httpd on

# chkconfig mysqld on

# chkconfig vsftpd on

# chkconfig sshd on


Configuring Apache


Apache runs as the httpd service, and it’s configuration file is contained in /etc/httpd/conf. To run in a ‘virtual’ hosting environment, we will now configure the httpd.conf file. But first things first, lets backup the httpd.conf file!


# cd /etc/httpd/conf

# cp httpd.conf httpd.conf.backup


Now edit httpd.conf and make the following changes, substituting mydomain.com for your own domain:


ServerAdmin admin@mydomain.com

ServerName www.mydomain.com:80

NameVirtualHost *:80

DirectoryIndex index.html index.htm index.html.var




ServerAdmin admin@mydomain.com

DocumentRoot /home/.sites/_default/web

ServerName www.mydomain.com

ScriptAlias /cgi-bin/ /home/.sites/_default/cgi-bin/

ErrorLog /home/.sites/_default/logs/error_log

TransferLog /home/.sites/_default/logs/access_log



Options FollowSymLinks

Options +Includes

AllowOverride All



Save and exit the httpd.conf file and then restart the httpd service.


# /etc/init.d/httpd restart


Configuring VSFTP


VSFTP stands for Very Secure File Transfer Protocol. However using the installation defaults isn’t actually that secure as it allows anonymous access and doesn’t restrict which users can access the servers FTP service. In order to harden the security of VSFTP, several configuration changes must be made. Please note that some of these lines may be commented out by default, with a #, so remember to remove this if required.


# vi /etc/vsftpd/vsftpd.conf


anonymous_enable=NO

xferlog_file=/var/log/vsftpd.log

idle_session_timeout=600

nopriv_user=nobody

ascii_upload_enable=YES

ftpd_banner= **** WARNING - Your actions are being logged ****


pam_service_name=vsftpd

userlist_enable=YES

listen=YES

tcp_wrappers=YES

chroot_local_user=YES

userlist_deny=NO


Next, we need to configure vsftpd.userlist and specify which users can FTP to the server. This compliments the userlist_deny setting in vsftpd.conf. When set to NO, this makes the vsftpd.userlist file a list of users that ARE allowed to log in.


# vi /etc/vsftpd/user_list


Remove all of the users that are listed in this file by default, and add ONLY the users that require access to the FTP server.


Configuring MySQL


MySQL is configured using /etc/my.cnf, but prior to any configuration this configuration file has only the bare minimum required to start the MySQL daemon. However there are 5 templates that we can base the configuration on; my-huge.cnf, my-innodb-heavy-4G.cnf, my-large.cnf, my-medium.cnf, and my-small.cnf. These are each configured depending on the RAM and the priority that MySQL has on this server.


We will use my-medium.cnf as this has been based on a web server where MySQL is not the primary role of the server but could have frequent use. If you are hosting a few sites with light use then use my-small.cnf.


# cd /usr/share/doc/mysql-server-

# cp my-medium.cnf /etc/my.cnf


Once this has overwritten my.cnf, the mysqld service must be restarted.


# /etc/init.d/mysqld restart


Now the root password for MySQL must be set using the following command. Do NOT use the same root password as the Linux root password.


# mysqladmin -u root password


Setting up phpMyAdmin


Administration of MySQL is carried out using phpMyAdmin which is a free open source software package licensed under the GNU. Nearly all hosting providers use this, and is pretty much the de-facto standard these days.


1) Download phpMyAdmin,

2) Extract the contents to a directory called phpMyAdmin (case sensitive)

3) Transfer the phpMyAdmin directory to /home/.sites/_default/web (Use FTP and login using the user you setup previously, as described in the Configuring FTP using VSFTPD section).


Now we need to configure the confic.inc.php file as follows:


# vi /home/.sites/_default/web/phpMyAdmin/config.inc.php


Look for:


$cfg['Servers'][$i]['auth_type'] = 'config’;


Change ‘config’ to ‘http’ then restart MySQL.


# /etc/init.d/mysqld restart


You should now be able to log into phpMyAdmin by going to http://www.mydomain.com/phpMyAdmin. Log on using ‘root’ and the password you specified for MySQL. You will now be presented with the phpMyAdmin web control panel. By default, MySQL contains a test database which is not required, so as a security measure, this needs to be deleted. To do this, click on ‘Databases’, then tick test. Click ‘Drop’ and then click ‘Yes’ to confirm.

Part 3: Adding websites


In the following steps, we will base our configuration on a fictitious company called Happy Burger who has already registered the domain name, happyburger.net. We will point www.happyburger.net to the IP address of this web server. When you are creating your own site, substitute the customer name and domain name for that of the actual customer. * If a Happy Burger really exists, then this is in no way associated with them and is purely coincidental.


Create a User Account


The first step is to create a user account that will be associated with this website and be used to authenticate via FTP. When creating the password, make sure that it is at least 8 characters, alphanumeric, mixed case and includes numbers. I usually generate random passwords for this.


# adduser –s /sbin/nologin happyburger

# passwd happyburger


Creating the directory structure


Each website must have the following directory structure in order to support access logs, web statistics, .htpasswd files, CGI scripts and the public web directory.



/home/.sites/happyburger/: This path will contain a directory for each website. Each directory should be named after the customer name, in lowercase.

/home/.sites/happyburger/web/: This path contains the website contents (public root).

/home/.sites/happyburger/web/stats/: This path will contain the Webalizer statistics, and is password protected using .htaccess.

/home/.sites/happyburger/private/: This path is not accessible from the internet, and contains the .htpasswd file.

/home/.sites/happyburger/cgi-bin/: Apache uses this path as the CGI script directory, by using a script alias.

/home/.sites/happyburger/logs/: This path stores the log files that Apache generates.


Create the structure as follows:


# cd /home/.sites

# mkdir happyburger

# cd happyburger

# mkdir web cgi-bin private logs

# cd web

# mkdir stats


Now change the ownership of these directories, substituting <username> (in this case, happyburger):


# cd /home/.sites

# chown <username> happyburger -R


Configuring Apache


As Apache will be configured using multiple ‘virtual hosts’ we need to create a separate configuration file for each virtual host. To do this we will create a vhost directory, and configure the Apache configuration file to read each of these virtual host configurations.


# cd /etc/httpd/vhost (If this directory does not exist then you will need to create it)


Now we will create the virtual host configuration file for this particular website.


# vi happyburger.conf


Now enter the following into the newly created configuration file:


<VirtualHost *:80>

ServerAdmin admin@happyburger.net

DocumentRoot /home/.sites/happyburger/web

ServerName www.happyburger.net

ServerAlias happyburger.net

ServerAlias www.happyburger.com

ServerAlias happyburger.com

ScriptAlias /cgi-bin/ /home/.sites/happyburger/cgi-bin/

<Directory /home/.sites/happyburger/web>

Options FollowSymLinks

Options +Includes +ExecCGI

AllowOverride All

</Directory>

</VirtualHost>


Once this has been saved, we will then need to configure Apache to include this in the main configuration.


# vi /etc/httpd/conf/httpd.conf


At the end of the configuration file add the following line:


Include /etc/httpd/vhost/happyburger.conf


Now restart httpd:


# /etc/init.d/httpd restart


Configuring FTP (VSFTP)


Before the new account can login with FTP, you must add the new user to vsftp.user_list which contains a list of all accounts permitted to use the FTP service.


# vi /etc/vsftpd.user_list


Add the new user to the list.


Problems with Sendmail

When setting up my first Linux web server it was actually sendmail that caused me the most trouble. If you get the following errors:

<< 550-Verification failed for
<<< 550-Unrouteable address
<<< 550- does not appear to be valid. Sender verify
<<< 550 failed.
550 5.1.1 ... User unknown
<<<>

1) This is likely to be a problem with the hostname of the server. Check to make sure the hostname of the server (e.g. linuxweb.mydomain.com) can actually be resolved over the internet. The hostname must be the same in /etc/hosts, /etc/sysconfig/network, and /etc/mail/relay-domains.

2) The /etc/mail/local-host-names and /etc/mail/relay-domains file should contain the hostname of the server, and also localhost. If the relay-domains file does not exist, then you can create it.

3) Check /etc/hosts.allow and make sure it has sendmail:ALL

4) This is unlikely but it may be a problem with the sendmail configuration (/etc/mail/sendmail.cf). Do not edit /etc/mail/sendmail.cf directly, instead edit /etc/mail/sendmail.mc which is a meta-config file. When done, you can use m4 sendmail.mc > sendmail.cf to write the meta-config to the sendmail.cf file.

The sendmail.mc file has various entries beginning with dnl (do not load). For sendmail to work properly on a virtual hosting server then make sure you add dnl to the following:

dnl FEATURE(delay_checks)dnl
dnl FEATURE(`mailertable',`hash -o /etc/mail/mailertable.db')dnl
dnl FEATURE(always_add_domain)dnl
dnl FEATURE(`blacklist_recipients')dnl
dnl FEATURE(`relay_based_on_MX')dnl
dnl FEATURE(masquerade_envelope)dnl
dnl FEATURE(masquerade_entire_domain)dnl

Then, the following entries should be enabled (without dnl at the beginning)

FEATURE(`accept_unresolvable_domains')dnl
FEATURE(`no_default_msa',`dnl')dnl
FEATURE(`smrsh',`/usr/sbin/smrsh')dnl
FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable.db')dnl
FEATURE(redirect)dnl
FEATURE(use_cw_file)dnl
FEATURE(use_ct_file)dnl
FEATURE(local_procmail,`',`procmail -t -Y -a $h -d $u')dnl
FEATURE(`access_db',`hash -T -o /etc/mail/access.db')dnl

5) As a final resort, re-install sendmail then go back to step 1.

# yum remove sendmail sendmail-cf
# yum install sendmail sendmail-cf

REFERENCES
http://www.rayheffer.com/36/building-a-secure-web-server-with-centos-5-part-1/


Centos cgi-bin

SkyHi @ Tuesday, June 22, 2010

Multiple hosts layout

During these articles I will be talking about different operating systems, different web servers and different, er, stuff.

To make things easier to understand and reference between articles and systems, I will use a 'standard' layout for hosting multiple sites (virtual hosts). Let me explain the layout I use.


Differences

As you know, there are several differences between distributions and not just in libraries, package management and so on.

The default directory locations for serving domains also differs. Some default to /var/www/ and some to /srv/www/. Some organisations recommend /srv/domain.com/.

Consistency

The way I will use is not the only way, nor is it special or the 'Slicehost' way.

It is, however, one way of organising your domains in one place and will work across different operating systems and web servers.

I will also mention that if you are using a shared hosting environment on your Slice then do stick with the OS defaults. My method places the domain directories in my home directory.

I am the only user of my Slice and this is, as far as I am aware, the case with the vast majority of Slice users, so I do not have to be concerned about other users logging in and accessing my home directory (apart from the usual security measures that is).

Layout

My domains are laid in their own directories in my /home/demo/public_html folder (demo is my main user name).

In each domain, I have a standard set of folders including logs, cgi, private, public, backup and so on but feel free to add/delete directories as you see fit.

One advantage of this layout is consistency between technologies. A standard Ruby on Rails application will have many directories with the main content being served from the 'public' directory.

My layout coincides with this so my plain html and dynamic PHP content are also served from the domain.com/public directory.

I can't incorporate every technology into one layout but I think this covers most eventualities. Specific articles (such as using Capistrano) will note the differences.

Folders

Let's take a look at the folders in use throughout these articles:

Multiple Domain Layout

So in this example I have three domains - each in their own directory. I always class subdomains as separate from the 'main' domain. After all, they have different content.

Details

Let's look in detail at the domain1.com folder:

Domain Layout

The layout is quite simple once you get used to all the connections:

public: where publicly served files, images, etc are placed.

private: used for files you do not want in the public domain such as PHP mysql connection files.

cgi-bin: umm, the cgi-bin

logs: place domain logs here - it keeps them separate and easily accessible.

backup: I place daily database backups here - makes for easier slice backups.

Change

Naturally, add/delete folders as you see fit. However, this is the layout that will be used throughout the articles when it comes to domain configurations.

Also, do use the OS default if you feel more comfortable doing so. Simply adjust the paths used in the demonstrations.

PickledOnion.



CentOS - Apache Virtual Hosts #1

Now we have Apache installed and running, we can configure it to serve multiple domains using Virtual Hosts.

Do note the layout used in these articles is explained here - feel free to use the directories of your choice.


Create the Directory Layout

In this example we'll be creating two domains, domain1.com and domain2.com

As the default permissions only allow us, the 'demo' user, to browse our home folder, let's start off by giving Apache access to this folder as well:

chmod 755 /home/demo

OK, now we need to create the directory structure for our sites.

In your home directory create a 'public_html' folder:

cd ~
mkdir public_html

Now, for each domain we want to host, create a folder with a standard set of sub-folders:

mkdir -p public_html/domain1.com/{public,private,log,cgi-bin,backup}

and

mkdir -p public_html/domain2.com/{public,private,log,cgi-bin,backup}

That will create the folders public, private, log, cgi-bin and backup for each of our domains (domain1.com and domain2.com).

index.html

The content of the public folder is, entirely, up to you but for this example I am going to use a very simple HTML file so we can check that the virtual hosts work correctly:

For each domain let's create the index.html file:

nano public_html/domain1.com/public/index.html

add the following to the file:



domain1.com


domain1.com



Repeat the process so you have a similar file for domain2.com (simply replace all instances of 'domain1.com' with 'domain2.com).

Now that we have a basic structure for our two domains we can look at defining the two virtual hosts.

NameVirtualHosts

With the virtual hosts, one thing to note that often catches people off guard is the NameVirtualHost setting.

For each port that Apache listens to, we need to define a NameVirtualHost. The issue that people sometimes overlook lies in the fact that you can only define it once per port.

Be careful that you do not add the same NameVirtualHost twice as adding another one will cause warnings and errors.

Let's go ahead and uncomment the generic NameVirtualHost in the Apache configuration.

Navigate to the /etc/httpd/conf directory and open the main Apache configuration file (httpd.conf):

sudo nano httpd.conf

Towards the bottom of this file you will want to uncomment out the generic NameVirtualHost as follows:

# Use name-based virtual hosting.
#
NameVirtualHost *:80
#
# NOTE: NameVirtualHost cannot be used without a port specifier
# (e.g. :80) if mod_ssl is being used, due to the nature of the
# SSL protocol.

Now we can restart Apache to initiate the changes:

sudo /etc/init.d/httpd restart

The following warning will be displayed as we still need to add our VirtualHosts

Stopping httpd:                                            [  OK  ]
Starting httpd: [Thu Dec 11 02:06:13 2008] [warn] NameVirtualHost *:80 has no VirtualHosts
[ OK ]

Please keep in mind that this is only a warning and will not appear once we complete the following section.

Let's move on.

Custom Virtual Hosts

We've setup the basics and now we're ready to add our own virtual hosts so that we can start to serve our domains.

Let's create the vhost for domain1:

sudo nano /etc/httpd/conf/httpd.conf

At the bottom of the httpd.conf file, we need to add the following:

# Place any notes or comments you have here
# It will make any customization easier to understand in the weeks to come

# domain: domain1.com
# public: /home/demo/public_html/domain1.com/



# Admin email, Server Name (domain name) and any aliases
ServerAdmin webmaster@domain1.com
ServerName domain1.com
ServerAlias www.domain1.com


# Index file and Document Root (where the public files are located)
DirectoryIndex index.html
DocumentRoot /home/demo/public_html/domain1.com/public


# Custom log file locations
LogLevel warn
ErrorLog /home/demo/public_html/domain1.com/log/error.log
CustomLog /home/demo/public_html/domain1.com/log/access.log combined

OK good, now we need to reload Apache:

sudo /etc/init.d/httpd reload

Navigate

Now navigate to your site:

http://domain1.com

You should now see the contents of public/index.html being shown:

Domain1 Home Page

ServerAlias

Note that in the vhost file, we set a ServerAlias. Providing you have the DNS set up correctly you can also use that address:

http://www.domain1.com

Repeat as necessary

To create and enable domain2.com simply go through the process again:

sudo nano /etc/httpd/conf/httpd.conf
...
# Enter the details for domain2.com as per the example shown above

Then reload Apache:

sudo /etc/init.d/httpd reload

Finally, navigate to your second domain:

http://domain2.com
or


http://www.domain2.com

All being well, you will see the 'domain2.com' index file.

Log Files

As defined in your vhost in the Apache configuration, each domain has its own log files, lets take a quick look:

ls /home/demo/public_html/domain1.com/log/

The output is exactly as expected:

access.log  error.log

This makes for much easier analysis as each set of logs is self contained.

Default Vhost

Remember that although we created a vhost for domain1.com and domain2.com, if someone enters the IP address of the Slice they are served the contents of the domain1.com vhosts.

Why are they served from that vhost?

Apache searches the enabled vhosts from the top down. Therefore, once it finds a matching vhost for the IP address entered, the contents of that domain are displayed. As we setup domain1.com initially in this example, the contents for this domain will be shown if you enter your slice's IP address in a browser.

This is something to keep in mind when planning your websites. Do you want a particular domain to be the default? Do you want the IP address to have completely different content?

If you want the IP address to have separate content than your domains, you will need to create an additional vhost and use the IP of your slice as the ServerName.

Summary

We've gone into some detail here but, overall, setting up a virtual host is relatively easy. Of course, there are many settings and configurations to take into account but you should have your site up and running in no time.

The next virtual host article will look in more detail at some of the settings that are available and what they mean.

Mark



CentOS - Apache Virtual Hosts #2

Following on from the first CentOS - Apache Virtual Hosts article, we can now look in detail at some of the settings available to us in the Virtual Hosts file.

This will enable us to have complete control of the domain we want to serve.


Some of the settings discussed were introduced in the previous article but some are new.

Take the time to read through the explanations and you will soon have an understanding of how powerful vhosts actually are.

Email

ServerAdmin

ServerAdmin webmaster@domain.com

Sets the email address for the server administrator - this will be used if you have setup the server to contact you on errors. It is also shown in the ServerSignature (if set to 'Email' - see below)

Domain Name

ServerName and ServerAlias

ServerName domain.com
ServerAlias www.domain.com

Sets the domain name for the virtual host. You can have as many aliases as required. For example, you can have domain.com and domain.net point to the same content.

Note this is not a rewrite rule (we'll look at those later) but the domains defined here will serve the same content (assuming you have set the DNS to point to your Slice IP).

Index Files

DirectoryIndex

DirectoryIndex index.html

Defines the index file (the 'home' page that is shown on entering the domain address). Useful if you have want the user to be directed to an alternate page or to a non-standard home page.

Do note this is not a good way of redirecting users as they may go directly to a non specified page such as domain.com/index.php whilst the DirectoryIndex will only work for those entering domain.com.

Documents

DocumentRoot

DocumentRoot /home/demo/public_html/domain.com/public

The location of the domain's public files. Use an absolute path name.

Log Files

ErrorLog and CustomLog

LogLevel warn
ErrorLog /home/demo/public_html/domain.com/log/error.log
CustomLog /home/demo/public_html/domain.com/log/access.log combined

Set the Log levels and the location for the Virtual Hosts log files. Very useful for easy analysis of the domain statistics.

Error Documents

ErrorDocument

ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html

Used for all the standard error messages.

In these examples I have an 'errors' folder in my public directory. I created each error document and place them in the 'errors' folder. The paths shown are relative to the DocumentRoot folder defined above.

If not defined, Apache will generated its own error pages. Custom error pages are more user friendly and can be customized as much, or as little, as you want.

Apache Footers

ServerSignature

ServerSignature On

Sets whether the server details are displayed in any server generated error pages or index lists. Options are On, Off and Email.

Note the level of detail in the signature is configured via ServerTokens which cannot be set in the Virtual Hosts file - only in the main httpd.conf. See the Apache configuration #2 article for more details.

If set to Email, the ServerAdmin email will be displayed.

cgi-bin

ScriptAlias

ScriptAlias /cgi-bin/ /home/demo/public_html/domain.com/cgi-bin/

Options +ExecCGI

Enables the cgi-bin location as defined by the custom virtual hosts layout. You can, of course, leave the cgi-bin in the DocumentRoot location if you so wish.

Directory


Options FollowSymLinks

Set the Options for the specified directory - the example shown allows the Option FollowSymLinks to be enable for the public directory of domain.com

Listed below are further Options that can be set:

Directory Browsing

Options

Options -Indexes

To turn off directory browsing use '-Indexes' or 'None'. To turn them on, use '+Indexes'.

SSI

Options

Options -Includes

This Option disables Server Side Inlcudes.

Symlinks

Options

Options -FollowSymLinks

Enable or disable the option to follow symlinks. Be careful with this option as it can lead to security risks (inadvertently linking to configuration folders).

Dejay Clayton made a good suggestion in using SymLinksIfOwnerMatch instead of FollowSymLinks.

The SymLinksIfOwnerMatch allows symbolic links to be followed only if the owner of the link is identical to the owner of the target file or directory. Thus preventing many of the security risks than a simple FollowSymlinks can create.

.htaccess

AllowOverride

AllowOverride None

Setting AllowOverride to none disables .htaccess support. Set to All to allow them.

You can also specify which .htaccess features to enable such as:

AllowOverride AuthConfig Indexes

The Apache AllowOverride docs has more information on the different features.

Remember to specifically protect your .htaccess file. This can be done in two ways:

Firstly rename it to something obscure and, secondly, deny access to the file from external sources:

AccessFileName .myobscurefilename

Order allow,deny
Deny from all
Satisfy All

No Options

Options

Options None

This will turn off all the available options.

Hierarchy

Remember that the Options directives can be set per directory like this:


AllowOverride None
Options None



AllowOverride All

This will turn of all Options and disable .htaccess support for all directories.

However, the second Directory setting will override the first and allow .htaccess support for the domain.com/public directory.

Summary

The Virtual Hosts directive is at once an easy tool to use and a very powerful one. My advice is to enter one setting and test it. Then enter the next setting and so on.

Once familiar you will see you have fine control over all of your web folders and files.

REFERENCES

http://articles.slicehost.com/2007/9/13/multiple-hosts-layout

http://articles.slicehost.com/2008/12/12/centos-apache-virtual-hosts-1

http://articles.slicehost.com/2008/12/12/centos-apache-virtual-hosts-2



Change TimeZone in your Linux Server quickly

SkyHi @ Tuesday, June 22, 2010
In any Red Hat based (RHEL/CentOS/Fedora) Server, change time zone to PST/PDT quickly:

# mv /etc/localtime /etc/localtime.old && ln -s /usr/share/zoneinfo/PST8PDT /etc/localtime

or set zone to IST:

# mv /etc/localtime /etc/localtime.old && ln -s /usr/share/zoneinfo/Calcutta /etc/localtime

or Set the TZ environment variable for quick display time according to preferred Time Zone:

# export TZ=America/Los_Angeles

and then view the output of date command.

or If you have the utility rdate, update the current system time by executing

# rdate -s pool.ntp.org

or You can execute ’system-config-date’ for setting up date/time and time zone:

# system-config-date

or better install ntp to sync date/time automatically from time server:

# yum install ntp

# chkconfig ntpd on

# ntpdate pool.ntp.org

# /etc/init.d/ntpd start



If you’re using Ubuntu, tzconfig is there for you:

# tzconfig


REFERENCES
http://linuxadminzone.com/change-timezone-in-your-linux-server-quickly/



 

Change timezone on CentOS

Here’s how to change the timezone on CentOS/RHEL;
cp /usr/share/zoneinfo/Europe/Brussels /etc/localtime

REFERENCES
http://blog.connexeon.com/sysadmin/linux/change-timezone-on-centos/




Centos – how to setup timezone

 

Step 1: Basically
ln -s /usr/share/zoneinfo/UTC /etc/localtime
date
Tue Nov 9 10:54:12 CET 2010 (this is wrong!!)
Step 2: So,
yum install ntp
chkconfig ntp on
ntpdate pool.ntp.org
service ntpd start
date
Tue Nov 9 09:58:16 CET 2010
Step 1: Basically
ln -s /usr/share/zoneinfo/UTC /etc/localtime
date
Tue Nov 9 10:54:12 CET 2010 (this is wrong!!)
Step 2: So,
yum install ntp
chkconfig ntp on
ntpdate pool.ntp.org
service ntpd start
date
Tue Nov 9 09:58:16 CET 2010

REFERENCES
http://shamuntoha.wordpress.com/2010/11/09/centos-how-to-setup-timezone/

Install html2ps/pdf library to create PDF files using php

SkyHi @ Tuesday, June 22, 2010

Generating PDF or postscript files on the fly with php is quite easy using a library called html2ps/pdf. Following are the steps which I took to install it on a fedora 7 server running php 5.x


As per the documentation, html2ps/pdf requires either Ghostscript or PDFLIB libraries for fast pdf generation. You can also use the inbuilt FPdf routines but that’s much slower. PDFLIB is non-free library which may requires you to have a license to use, therefore, I opted for GhostScript here.


Step 1. Check whether ghostscript is already installed or not:


# which gs

/usr/bin/which: no gs in (/usr/kerberos/sbin:/usr/kerberos/bin: //sbin://bin: /usr/local/sbin: /usr/local/bin:/sbin: /bin:/usr/sbin:/usr/bin:/root/bin)


as you can see above, gs binary is not installed. if its available in your system then jump to step 3 else proceed to its installation in step 2.


Step 2. Download, compile and install ghostscript library:


# cd /usr/src

# wget http://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/gs863/ghostscript-8.63.tar.gz

# tar xzf ghostscript-8.63.tar.gz

# cd ghostscript-8.63

# ./configure

# make

# make install


you can verify installation by issuing:


# which gs

/usr/local/bin/gs


Step 3. download and unzip the html2ps/pdf library:


# cd /usr/src

# wget http://www.tufat.com/files_lgpl/script_19.zip

# unzip script_19.zip

# cd html2ps_v2042/


you will find a public_html directory here having php files and related directories. They needs to be transferred to some other locations where Apache can access them. let’s store in /var/www/html/html2ps directory. (I assume /var/www/html is your DocumentRoot here).



# mkdir /var/www/html/html2ps

# mv public_html/* /var/www/html/html2ps

# cd /var/www/html/


change ownership to apache:


# chown apache:apache html2ps/ -R


Step 4. Update html2ps/pdf library config file to find out ghostscript binary for pdf creation.


# cd /var/www/html/html2ps

# vim config.inc.php

//update line where path of Ghostscript executable required, in my case it’s in line 27.

define(‘GS_PATH’,'/usr/local/bin/gs’);


save and exit.


Library is installed, you should be able to use it using http://localhost/html2ps/index.php URL now.


REFERENCES

http://linuxadminzone.com/install-html2pspdf-library-to-create-pdf-files-using-php/

Top 5 most useful commands or tools for Linux administrators

SkyHi @ Tuesday, June 22, 2010

There are plenty such tools which are definitely very useful for Linux admins. Here I am just trying to figure out 5 of such useful tools which are used by a normal Linux administrator in day to day operations. A tool which I think is most useful may not fit in your usage and its definitely possible that you know some awesome tool which I forgot to include here, for such case, I am requesting hereby to please mention the tool in comments. One more thing, I am mentioning here tools which are somewhat optional and not absolutely required for everybody and excluding tool which have no viable alternative and every Linux admin have to use them.. such as SSH, SCP etc.

#5. head/tail

Most of time, the sole purpose of logging in a server is to diagnose some issue and the common way to start this is to look at logs. Logs of different applications like Apache, MySQL, mail logs etc. What you use to look at logs? isn’t that tail? similarly we sometimes use ‘head’ to check few starting lines of any file.

Few examples:

* Continuously check Apache error log file:

$ tail -f /var/log/httpd/error_log

* View first 15 linues from MySQL log:

$ head -15 /var/log/mysqld.log

#4. vi/nano/emacs

Text editor basically needed frequently to create/update config files. I prefer vim, simply because I am very comfortable with it and remembers some of its useful commands for quick editing.

few example of working with vi. open a file with vi and without going in insert mode, here are useful character you can press:

=> jump to end of line
$
=> start of line
0
=> Delete rest of line
D
=> Repeat the last command given:
. (dot)

=> add 'maal' to the end of every line. 1 is line 1, $ is the last line
:1,$ s/$/maal/

=> put 'bingo' at the start of lines 5-10
:5,10 s/^/bingo/

=> change foo to bar for all occurrences in the rest of the file from where the cursor is
:s/foo/bar/g

=> Delete current line and got into insert mode.
C

=> Remove the ^M from files that came from windows:
:se ff=unix

=> Turn on/off display of line numbers:
:set nu
:set nonu

=> if you want actual line numbers in your file:
:%!cat -n

=> find the word under cursor
* (star)

#3. screen

screen is one of much underutilized command in nix world. take a scenario, when last time you issued a command in remote server and find out that the command will take hours to complete? or you are in need to login in 10 servers and check something.. copy files among them.. and voila.. your internet connection get reset and your ssh session get terminated. Here comes screen, once you start using it, you will get hooked to it. Screen is a terminal multiplexer that allows you to manage many processes (like ssh sessions) through one physical terminal. Each process gets its own virtual window, and you can bounce between virtual windows interacting with each process.

Let me give you more insight. Suppose you have many servers and ideally you should restrict ssh (port 22) access to selected IPs only. So, you login into one server which allows access from remote IPs. You can start screen there by typing ‘screen’ (all major Linux distributions have screen already installed). You can see a status bar. create new screen windows by pressing Ctrl+ac. switch between them by pressing Ctrl+an (next) and Ctrl+ap (previous). Basically, for b It offers very useful features like Remote terminal session management (detaching or sharing terminal sessions), unlimited windows (unlike the hardcoded number of Linux virtual consoles), copy/paste between windows, notification of either activity or inactivity in a window, split terminal (horizontally and vertically) into multiple regions, sharing terminals etc.

You can save your preferences in .screenrc, like here’s my .screenrc where I’ve redefining status bar look and feel and assigning key f5 (previous window) and f6 (next window):

$ cat ~/.screenrc
# no annoying audible bell, please
vbell on

# detach on hangup
autodetach on

# don't display the copyright page
startup_message off

# emulate .logout message
pow_detach_msg "Screen session of \$LOGNAME \$:cr:\$:nl:ended."

# advertise hardstatus support to $TERMCAP
termcapinfo xterm* ti@:te@

# make the shell in every window a login shell
shell -$SHELL

defscrollback 10000

# Extend the vt100 desciption by some sequences.

termcap vt* AF=\E[3%dm:AB=\E[4%dm
caption always
caption string '%{= wk}[ %{k}%H %{k}][%= %{= wk}%?%-Lw%?%{r}(%{r}%n*%f%t%?(%u)%?%{r})%{k}%?%+Lw%?%?%= %{k}][%{b} %d/%m %{k}%c %{k}]'

# keybindings

bind -k F5 prev
bind -k F6 next

#2. netstat/nmap

These are very useful commands to diagnose things about network. of course, ping/traceroute may be most commonly used ones but the usefulness wise, nmap and netstat are more useful than a basic ping. netstat stands for network status. nmap is a sort of security/port scanner or you can say a network exploration command.

few examples of netstat:
* Display total number of internet (port 80) connections:

$ netstat -an |grep :80 |wc -l

* Display all ports your machine listening on:

$ netstat -ant | grep LISTEN

* Scan a machine on your LAN with nmap and know which ports are open on it:

$ nmap ip

#1. find and grep
List of some routine tasks: How many files are there consuming most of disk space? Delete all temporary files older than 2 days, find out how many files have old server name written in them which is causing issue? rename all ‘.list’ to ‘.txt’. The commands find, grep are your best friend here.

Find command is used to search for files. you can specify many options with it like files created today or having size greater then you specified. Normally we also combine find with xargs or exec to issue commands on files returned by find.

examples of find command:
* find top 10 largest files in /var:

$ find /var -type f -ls | sort -k 7 -r -n | head -10

* find all files having size more than 5 GB in /var/log/:

$ find /var/log/ -type f -size +5120M -exec ls -lh {} \;

* find all today’s files and copy them to another directory:

$ find /home/me/files -ctime 0  -print -exec cp {} /mnt/backup/{} \;

* find all temp files older than a week and delete:

$ find /temp/ -mtime +7-type f | xargs /bin/rm -f

* find and rename all mp3 files by changing their uppercase names to lowercase:

$ find /home/me/music/ -type f -name *.mp3 -exec rename 'y/[A-Z]/[a-z]/' '{}' \;

some examples of grep command:

* Print Apache’s documentroot directory name:

$ grep -i documentroot  /etc/httpd/conf/httpd.conf

* View file contents without comments and empty lines:

$ grep -Ev “^$|^#” /etc/my.cnf

* print only IP address assigned to the interface:

$ ifconfig eth0 | grep 'inet addr:' | cut -d':' -f2 | awk '{ print $1}'

* How many email messages sent for a particular date:

$ cat /var/log/maillog | grep "status=sent" | grep "May 25" | wc -l

* Find out a running process/daemon from process list (thanks to staranneph for recalling this):

ps -ef | grep mysql

* You can also note cpu/mem usage by using above. like in below command output, you can see that Plesk’s statistics process is utilizing more than 18% cpu alone:

[root@myserver ~]# ps aux | grep statistics
root 8183 18.4 0.0 58384 2848 ? D 04:05 3:00 /usr/local/psa/admin/sbin/statistics

I would like to know your thoughts, any command / tool you think should be included in top 5 here.


REFERENCES
http://linuxadminzone.com/page/3/

Monday, June 21, 2010

Duplicate Emails in Your Inbox.

SkyHi @ Monday, June 21, 2010

You delete them but they keep coming back, this is usually caused by a corrupted email in your inbox, a setting in your email client, or a large message in your inbox usually over one Megabyte in size.

Some things to try to fix this problem:

  1. Open your email client
  2. Click Tools at the top > Click Accounts
  3. Go to the mail tab
  4. Click Properties to the right
  5. Click on the Advanced tab at the top right
  6. Uncheck leave a copy of messages on server. That some times gets checked when it is not wanted and can cause this issue.

The other cause of repeated emails is a corrupt message in the inbox, the best way to fix this problem is to use web mail to check all messages and delete the one that does not look familiar or you cannot read it as it is garbled. A lot of times a corrupt message will have �no subject� and �no sender.�

To get into web mail and remove these messages do the following:

  1. Open Internet Explorer or your default browser
  2. Type www.vcn.com in the address bar hit enter or click Go
  3. Click Login at the top right of the page
  4. Select e-mail address under the middle or web mail section, type in your email address
  5. Put in your password for that email address
  6. Click login
  7. Find the corrupt message, sometimes to find it you will have to look through your messages and try and read them. If there are garbled words in a message or the message in its entirety is garbled that is usually the message causing the problem.
  8. With the message highlighed, click Delete in the upper left corner of the page. This marks the message for removal.
  9. Click Purge deleted on the right side of the page to remove the message from your inbox.�

Repeat steps 1-6 for a large message in your inbox and steps 8-9. to remove the large message. Here you are looking for a message size of 1MB or more (shown on the right side of the page). Remember anything larger than 1MB and if you are having a slow connection something around 700KB and up can also cause this problem. Dialup users are usually the only customers that have this issue due to the lack of bandwidth available for a standard modem connection.


REFERENCES

http://www.vcn.com/knowledgebase/article.php?id=308

Why do I get duplicate emails?

SkyHi @ Monday, June 21, 2010

Once in a while customers may receive a single email message more than one time. The messages are identical, with matching content and "Sent" dates. This article explains one common reason for receiving duplicate messages.



How Email Servers Deliver Mail


Assume that we're talking about a message from bob@sendingserver.com to sue@receivingserver.com.



  1. After both servers negotiate a connection the mail server for sendingserver.com pushes the message to the receiving mail server.


  2. While holding the connection open receivingserver.com scans the message for spam and viruses.


  3. Once the message has been declared safe for delivery receivingserver.com queues it for local delivery to sue's mailbox.


  4. When the message finally reaches sue's mailbox on receivingserver.com a message is sent back to sendingserver.com that informs it of a successful delivery.


This process works to ensure that all email is properly scanned, delivered and accounted for. However in very rare cases an interruption between step 3 and 4 can cause a message to be delivered more than once.



For example if the connection is interrupted after receivingserver.com queues it for local delivery but before a confirmation can be sent back to sendingserver.com the sending server will try to redeliver the message.



Since the original copy was queued for local delivery it will come through, but since the sending server never received confirmation it will try to deliver again resulting in duplicate emails. This situation is more likely to happen under intense load situations or with high latency network connections. The issues leading to the interrupted connection can originate on either the sending server's end or with the receiving server.



The above situation is temporary and normally only a few copies will be delivered, they can be deleted safely.


REFERENCES

http://kb.mediatemple.net/questions/774/Why+do+I+get+duplicate+emails%3F