Apache Rewrite rules how to fix .com to .co.uk URL’s

The wonderful world of looking after web servers came up this week, there were two requirements. One to satisfy our marketing department and the other to stop some kids driving up the CPU of one of our web servers.

The marketing requirement was to allow both a .co.uk and a .com domain to be the same web site, this is easy DNS stupid!! but display the .com address in the URL and not the .co.uk

I new instantly that this meant learning Apache rewrite rules, I was later found that I was in for a world of pain and 4 hours later had a test bed environment that looks like it should work. There are a ton of references on the interweb and Google again is your friend.

A couple of places that are worth a note are the actual Apache docs, these were actually not to bad, in both trying to understand them and the examples that they gave.

Apache links

http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html

https://httpd.apache.org/docs/trunk/vhosts/examples.html

 

Not everything should be done with re-write rules and one issue was discussed on a train journey this morning with a fairly knowledgeable guy. Not a clue what his name was but cheers mate 🙂

The following solutions to change the URL and to stop someone abusing our server is made up of both rewrite rules and virtual hosts.

OK in this example we will introduce a few test domains :-

www.test.com, www.test.co.uk, www.nonsense.eu

To try this out you need obviously a Apache server and access to your hosts file.

So if you are on Linux then edit your /etc/hosts file with the following:-

ip address of server www.test.com www.test.co.uk test.com test.co.uk www.nonsense.com

I am running the web server on my laptop so my hosts file looks like this

127.0.0.1 http://www.test.com http://www.test.co.uk test.com test.co.uk www.nonsense.eu

So now to edit the httpd.conf file, this was done with a yum install so the httpd.conf file is

vi /etc/httpd/conf/httpd.conf

Insert the following and try it out. I will explain more at the end 🙂

Note that some of the lines should not be used in production, more about this again at the end of the post.

 

<VirtualHost *:80 >
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /var/www/html/livesite/
ServerName www.test.co.uk
ErrorLog logs/test.com-error_log
CustomLog logs/test.com-access_log common
</VirtualHost>

<VirtualHost *:80 >
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /var/www/html/livesite/
ServerName test.co.uk
ErrorLog logs/test.com-error_log
CustomLog logs/test.com-access_log common
# Make the test.com into the www.test.co.uk
RewriteEngine on
RewriteCond %{HTTP_HOST} ^test\.co.uk$ [NC]
RewriteRule (.*) http://www.test.co.uk$1 [L,R=301]
RewriteLogLevel 9
RewriteLog logs/test.co.uk-rewrite.log
</VirtualHost>

<VirtualHost *:80 >
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /var/www/html/livesite/
ServerName www.test.com
ErrorLog logs/test.com-error_log
CustomLog logs/test.com-access_log common
RewriteEngine on
# Make the .com into the .co.uk address
RewriteCond %{HTTP_HOST} ^(www\.)?test\.com$ [NC]
RewriteRule (.*) http://www.test.co.uk$1 [L,R=301]
# Make the test.com into the www.test.co.uk
RewriteCond %{HTTP_HOST} ^test\.com$ [NC]
RewriteRule (.*) http://www.test.co.uk$1 [L,R=301]
RewriteLogLevel 9
RewriteLog logs/test.com-rewrite.log
</VirtualHost>

<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /var/www/doone/
ServerAlias *
ErrorLog logs/nottest.com-error_log
CustomLog logs/nottest.com-access_log common
RewriteEngine on
RewriteCond %{HTTP_HOST} !^(www\.)?test\.co.uk$ [NC]
RewriteRule (.*) http://www.google.com$1 [L,R=301]
RewriteLogLevel 9
RewriteLog logs/catchall-rewrite.log
</VirtualHost>

You will also need to run the following just to set you the test directories

 

mkdir /var/www/html/livesite
mkdir /var/www/html/livesite/test
mkdir /var/www/doone
echo <html> >>/var/www/html/livesite/index.html
echo <body> >>/var/www/html/livesite/index.html
echo It works >>/var/www/html/livesite/index.html
echo </body> >>/var/www/html/livesite/index.html
echo </html> >>/var/www/html/livesite/index.html 
echo <html> >>/var/www/index.html
echo <body> >>/var/www/index.html
echo Do One >>/var/www/index.html
echo </body> >>/var/www/index.html
echo </html> >>/var/www/index.html

 

OK now try it out,

 

You should be redirected to www.test.co.uk if you type www.test.com / test.com / test.co.uk / www.test.co.uk

If you enter though www.nonsense.eu, you should be redirected to www.google.com

The order of the virtual hosts was important in getting this correct, also note that this does not include the symlinks and other goodies that are contained usually with in the httpd.conf file. Again this is only to demonstrate how to get this up an running

Okay now for a bit of direction

All standard in bold as per normal installs

<VirtualHost *:80 >

ServerAdmin webmaster@dummy-host.example.com

DocumentRoot /var/www/html/livesite/

ServerName test.co.uk

ErrorLog logs/test.com-error_log

CustomLog logs/test.com-access_log common

Now here is some of the clever stuff.

# Make the test.com into the http://www.test.co.uk

You need to turn the engine on

RewriteEngine on

This looks out for test.co,uk

RewriteCond %{HTTP_HOST} ^test\.co.uk$ [NC]

This converts it into http://www.test.co.uk

RewriteRule (.*) http://www.test.co.uk$1 [L,R=301]

As you would have expected there was a lot of debugging required as I was just starting out with this, so to enable debugging you turn it on and then specify where you want the log file, this should be turned of when using it in a production server

RewriteLogLevel 9

RewriteLog logs/test.co.uk-rewrite.log

</VirtualHost>

 

Ok the next two virtualhosts are the same, the last one is a catch all, and in this circumstance will through you out to a different web address completely. In this circumstance just through them out to Google or a static html holding page, something that does not require much processing.

 

Again standard stuff in bold

<VirtualHost *:80>

ServerAdmin webmaster@dummy-host.example.com

DocumentRoot /var/www/doone/

ServerAlias *

ErrorLog logs/nottest.com-error_log

CustomLog logs/nottest.com-access_log common

This is the clever bit, not the ! In the front of the string being inspected

RewriteEngine on

So if the URL is not www.test.co.uk fire the rule

RewriteCond %{HTTP_HOST} !^(www\.)?test\.co.uk$ [NC]

Bounce the request out to Google

RewriteRule (.*) http://www.google.com$1 [L,R=301]

Again logging was switched on to see what was happening

RewriteLogLevel 9

RewriteLog logs/catchall-rewrite.log

</VirtualHost>

 

That’s all folks as bugs used to say :). Check back as I suspect there will be more to come when this gets put live.


APC installation in a Apache PHP environment

This year I wrote on how best to install Sugar CRM including installing the APC cache engine. I have just had call to install this again, and thought that really this could have a section of its own. I am a novice in the whole APC cache arena, but I a lead to believe that is works (and it does) straight out the box as they say. But you can tune, clear rotate the cache with the change of some settings, this maybe something that I look at in the future.

Anyway this is how you install it

Please note you will need the php-devel package installed. This may break your environment if you are running a non up todate PHP environment. Take note that the yum install will install the newest version of PHP that is contained in the repository..

yum install -y php-devel pcre pcre-devel
mkdir /opt/software
cd /opt/software
wget http://pecl.php.net/get/APC-3.1.9.tgz

tar -xvzf  APC-*.tgz

cd APC-*

phpize

You should receive the following

Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
config.m4:180: warning: AC_CACHE_VAL(PHP_APC_GCC_ATOMICS, …): suspicious cache-id, must contain _cv_ to be cached
../../lib/autoconf/general.m4:1974: AC_CACHE_VAL is expanded from…
../../lib/autoconf/general.m4:1994: AC_CACHE_CHECK is expanded from…
config.m4:180: the top level
config.m4:180: warning: AC_CACHE_VAL(PHP_APC_GCC_ATOMICS, …): suspicious cache-id, must contain _cv_ to be cached
../../lib/autoconf/general.m4:1974: AC_CACHE_VAL is expanded from…
../../lib/autoconf/general.m4:1994: AC_CACHE_CHECK is expanded from…
config.m4:180: the top level

To configure APC you need to know where the php-config file was installed

whereis php-config

This should return something like

/usr/bin/php-config

When I ran .configure and make I got the following error, this was because I got the path statement wrong for the php-config file. Be careful it took me 20 minutes to work out what was wrong, copy and pasting has a lot to answer for 🙂

In file included from /opt/software/APC-3.1.9/apc.c:44:
/usr/include/php/ext/pcre/php_pcre.h:29:18: error: pcre.h: No such file or directory
In file included from /opt/software/APC-3.1.9/apc.c:44:
/usr/include/php/ext/pcre/php_pcre.h:37: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
/usr/include/php/ext/pcre/php_pcre.h:38: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
/usr/include/php/ext/pcre/php_pcre.h:44: error: expected specifier-qualifier-list before ‘pcre’
/opt/software/APC-3.1.9/apc.c:393: error: expected specifier-qualifier-list before ‘pcre’
/opt/software/APC-3.1.9/apc.c: In function ‘apc_regex_compile_array’:
/opt/software/APC-3.1.9/apc.c:454: error: ‘apc_regex’ has no member named ‘preg’
/opt/software/APC-3.1.9/apc.c:454: error: ‘apc_regex’ has no member named ‘preg’
/opt/software/APC-3.1.9/apc.c:455: error: ‘apc_regex’ has no member named ‘nreg’
/opt/software/APC-3.1.9/apc.c:455: error: ‘apc_regex’ has no member named ‘nreg’
/opt/software/APC-3.1.9/apc.c: In function ‘apc_regex_match_array’:
/opt/software/APC-3.1.9/apc.c:487: error: ‘apc_regex’ has no member named ‘preg’
/opt/software/APC-3.1.9/apc.c:487: error: ‘apc_regex’ has no member named ‘preg’
/opt/software/APC-3.1.9/apc.c:488: error: ‘apc_regex’ has no member named ‘nreg’
/opt/software/APC-3.1.9/apc.c:488: error: ‘apc_regex’ has no member named ‘nreg’
make: *** [apc.lo] Error 1

./configure –enable-apc –enable-apc-mmap –with-php-config=/usr/bin/php-config

make

make install

This has now installed apc, you need to tell php about this now.

There are two ways to do this depending on the version of php I believe, this is what I have surmised from the php.ini file from the following

;;;;
; Note: packaged extension modules are now loaded via the .ini files
; found in the directory /etc/php.d; these are loaded by default.
;;;;

If you do not have this note then just add the following to the file.

extension=apc.so

If you do have reference to the php.d directory then

echo "; Enable apc extension module"  > /etc/php.d/apc.ini
echo "extension=apc.so"  >> /etc/php.d/apc.ini

You have to restart the Apache server  if it is started

service httpd restart

httpd: apr_sockaddr_info_get() failed for

I configure many Apache servers from scratch and I always forget how to fix the error

 httpd: apr_sockaddr_info_get() failed for

 

It is pretty easy, you edit the httpd.conf file and look for

# If your host doesn’t have a registered DNS name, enter its IP address here.
#
#ServerName http://www.example.com:80

 

Edit the ServerName entry to match your DNS servername.

The httpd.conf file could be anywhere depending on how you installed the server, common places are

/etc/httpd/conf/ and /var/www/apache2/conf

 

Once you have changed the file restart the server and this should eliminate the errors


Apache Virtual Host Configuration

Arrrrrgggggghhhhh!!!!!!!

Linux and Apache great and frustrating all at the same time, how can this be !!!!!!!

Configuring an Apache server to run multiple web sites, nothing hard in that I hear you say.

For those who need a quick lesson, find the httpd.conf file and add lines of code at the end to mirror something like this.

httpd.conf is usually foounf in /etc/httpd/conf or /usr/local/apache2/conf depending on how it was installed.

To host multiple site you use the virtualhost parameters. So a simple site config is to host http://www.acmetest.com on the local server

<VirtualHost *:80>
ServerName www.acmetest.com
DocumentRoot /usr/local/apache2/htdocs/acme
<Directory “/usr/local/apache2/htdocs/acme”>
Options -Indexes +FollowSymLinks +ExecCGI
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

So you would think this would work, but the default web server was still serving out the index.html page. After 1 hour of trying to work out what is wrong with these few lines I remembered in the back of my addled brain SElinux.

At a command line

setenforce 0

Restart the web server and hey it WORKS!!!!

This is not advisable for production systems. There is more regarding how to allow Apache configuration and SELinux on the Centos Wiki. Navigate to Section 5.

I will be looking at further on a little later and let you know what the commands are to get a working site with SELinux enabled.

 


Compile and Install Apache, PHP, PHPAdmin, Webmin and IPTables on Debian

Please note this is not complete.

 

But this one is Install Apache, PHP, PHPAdmin and its is much better, for a start it works, its complete and we use it in production.

We are launching a Drupal web site and as per best practices require that the web server be built only with the relevant modules required. This mean compiling the Apache code from source, to achieve this there are a few steps to go through as you would expect.

Our partner wants this on the Debian platform which is not my preference but to keep things tidy I have agreed. This is also running on the Amazon AWS platform and therefore additional packages need to be installed as some of the base images are very vanilla.

Again as always apology for some of the basic nature of the syntax i.e. cd .. but these guides are meant for all levels of Linux user and I only class myself as intermediate at best.

You need the following packages on the server to complete the installation

apt-get install gcc make libtool g++ zlib1g zlib1g-dev  

If you plan on using PHP you will need

apt-get install libxml2

If you plan on using mysql with the installation (please note that this will just load the client and my mysql server in on another server)

apt-get install mysql-client libmysqlclient-dev

The start of the installation

cd ~

mkdir software

cd software

download the apr and apr-utility

wget http://mirrors.ukfast.co.uk/sites/ftp.apache.org//apr/apr-1.4.6.tar.gz
wget http://mirrors.ukfast.co.uk/sites/ftp.apache.org//apr/apr-util-1.4.1.tar.gz
tar xzvf apr-1.4.6.tar.gz
tar xzvf apr-util-1.4.1.tar.gz

cd apr-1.4.6

./configure
make
make install

cd ..

cd apr-util-1.4.1
./configure –with-apr=/usr/local/apr

make

make install

cd ..
wget http://sourceforge.net/projects/pcre/files/pcre/8.21/pcre-8.21.tar.gz
tar zxvf pcre-8.21.tar.gz
cd pcre-8.21
./configure
make
make install

To ensure that the server starts make sure you use this command, this creates all the links required for the shared libraries.

ldconfig

To install the Apache server

cd ..

wget http://mirror.catn.com/pub/apache//httpd/httpd-2.4.1.tar.gz

tar zxvf httpd-2.4.1.tar.gz

cd httpd-2.4.1

./configure –prefix=/opt/httpd \

./configure –enable-so \
–enable-authz_host –enable-mod_dir –enable-log_config \
–enable-mime –enable-rewrite –enable-setenvif –enable-alias \
–enable-expires –enable-headers –enable-deflate –enable-include \
–with-included-apr=/usr/local/apr

Note the /opt/httpd (I can not find anywhere a best practice on where to compile the installation so I have chosen /opt as this is for none base packages and even though Apache is always linked with Linux it could be considered third party 🙂 ). If there is anyone who disagrees please let me know and I will change the instructions accordingly.

I found out that if you leave the prefix out you get the default install which is never a bad thing. It will install it in /usr/local/apache2

make

make install

To test if the server starts

cd /usr/local/apache2/bin

./apachectl -k start

./apachectl -k stop

Now the PHP installation

cd ~

cd software

wget  http://uk3.php.net/get/php-5.3.10.tar.gz/from/this/mirror

mv mirror php.tar.gz

tar xzvf php.tar.gz

cd php-5.3.10

./configure –with-apxs2=/usr/local/apache2/bin/apxs –with-mysql=/usr/include/mysql

make

make install

cp /root/software/php-5.3.10/php.ini-production /usr/local/lib/php.ini

cd /usr/local/apache2/bin

./apachectl -k start

./apachectl -k stop