Saturday 22 November 2008

Sendmail stat=Deferred: Name server: host name lookup failure

It's a saturday. I have just spent 4 1/2 hours making sendmail actually work on a development server. All other websites I found gave me useless information on how to fix this, So I thought I'd post my fix here to Save countless hours of your weekend....

I kept receiving the followingerror

stat=Deferred: Name server: host name lookup failure

in my maillog file.

The main crox of the problem is that I set up a FC9 development server on my local network without installing Bind. At the time I didn't want to use Bind, which is a common thing not to have on a development server. However, sendmail doesn't look at my hosts file to resolve network addresses... oh no, why be so simple! instead isendmail decides to ignore my hosts file and visits the router to find out where localhost is. Therefore, to fix this problem, you need to install bind and just setup a localhost.

You Need to install Bind on your server to get Sendmail to work.



Don't rely on your hosts file. If you are unfamiliar with using Bind, on fedora you can just type; yum install bind bind-chroot. You can setup a simple configuration using this guide.

After you have Bind setup, you will then need to edit your network settings to make sure all DNS requests look to your server first, before going to the internet to resolve. So edit this file;

vi /etc/sysconfig/networking/devices/ifcfg-eth0

and change

DNS1=192.168.1.1

to

DNS1=127.0.0.1
DNS2=192.168.1.1

Restart your server and make sure that sendmail and bind are both up and running. Then try crossing your fingers, finding some wood to touch and then sending an email.

For me, this worked a treat and shows in my case that Sendmail completely ignores my hosts file and goes straight for the servers primary DNS setting.

Friday 19 September 2008

Apache Automatic Sites Using VirtualDocumentRoot

Right, so i hate having to go edit config files when i'm editing and changing loads of new sites every day. It's time consuming and it breaks up my development.


I have a Fedora linux development server setup. I have a staic ip address and I have bind setup and a domain (*.mydomain.com) with wildcard subdomains pointing to it. That allows me to make a new site on my subdomain per website i'm editing and then i can demonstrate that to clients without ftp-ing the site and uploading databases.


For example if i'm editing newsite.com, i download a copy to my dev server, then log into my dev server apache config file and add a virtualhost for newsite.com.mydomain.com I can then edit this version of the site, allow the client to approve the site, then ftp up my changes.


However, if you have over 20 of these sites it gets a bit confusing in your apache file, and it also breaks up development time when you edit the file, not to mention increasing the chance of you fucking things up.


Therefore, on a recent new install of my dev server, i decided to spend some time researching into apaches ability to rewrite stuff. I use mod_rewrite quite heavily and I wondered if it allows you to edit things before apache runs any php code. After much reading of peopletrying to do stupid nonsensical things with apache that have no real point... I happend across a way of doing this using the apache VirtualDocumentRoot. Here's an example;


<virtualhost>

ServerAlias *.mydomain.com

DocumentRoot /home/www/sites

VirtualDocumentRoot /home/www/sites/%-3+/

</virtualhost>


So, if you have <strong>sitea.com.mydomain.com</strong> this now maps to /home/www/sites/sitea.com/.


There is one small problem with this; If you use $_SERVER['DOCUMENT_ROOT'] in php, then this causes problems as document_root point to /home/www/sites. But, there's a work around for this. You have to make a php file to reset document_root and make that file run before anything else when the server requests this page. Here's an example of the php file;


<?

$location = explode(".",$_SERVER['HTTP_HOST']);

for($i=sizeof($location)-6; $i>=0; $i--) $lurl = '.'.$location[$i].$lurl;

$lurl = '/'.ltrim($lurl, '.');

$_SERVER[DOCUMENT_ROOT] .= $lurl;

?>


The above script resets the document_root variable correctly, Now you just need to edit the Apache config file;


<virtualhost>

ServerAlias *.mydomain.com

DocumentRoot /home/www/sites

VirtualDocumentRoot /home/www/sites/%-3+/

php_admin_value auto_prepend_file /home/www/set_path.php

</virtualhost>


Voila! You should now be able to make dev sites without having to worry about the apache config files ever again!

Monday 9 June 2008

MySQL PHP Database Ripper

Recently, I've been working on several projects where direct database access has been an issue.

To get around this, i've made a php mysql Database Ripper. It reads the database schema and then prints out the table structure and information for each table.

Here's the source - Enjoy :)


/************************************

db connection

************************************/

$host = "localhost";

$user = "dbuser";

$pass = "dbpassword";

$dbname = "dbname";


$db = mysql_connect($host, $user, $pass) or die(mysql_error());

mysql_select_db($dbname, $db) or die(mysql_error());


/***********************************************************/


$ic = 0;


$lsql = "show tables;";

if ($result = mysql_query($lsql)){

while ($row = mysql_fetch_array($result, MYSQL_NUM)){

$mySQLArray[$ic++] = $row[0];

}

mysql_free_result($result);

}


foreach ($mySQLArray as $litem){

$lsql = "SHOW COLUMNS FROM ".$litem.";";

$lreturn .=("create table ".$litem."(\r\n");

$lcount = 0;

if ($result = mysql_query($lsql)){

while ($row = mysql_fetch_array($result, MYSQL_NUM)){

if ($lcount > 0) $lreturn .=(",\r\n");

$lreturn .=($row[0]." ".$row[1]);

if ($row[2] == "NO") $lreturn .=(" NOT NULL ");

if ($row[4] != "") $lreturn .=(" default '".$row[4]."' ");

if ($row[3] == "PRI") $lreturn .=(" primary key ");

$lreturn .= (" ".$row[5]." ");

$lcount++;

}

mysql_free_result($result);

}

$lreturn .=(") ENGINE=InnoDB DEFAULT CHARSET=latin1;\r\n\r\n");

$lsql = "select * FROM ".$litem.";";

if ($result = mysql_query($lsql)){

while ($row = mysql_fetch_array($result, MYSQL_NUM)){

$lreturn .= "insert into ".$litem." values (";

$lstr = "";

foreach($row as $lrow){

$lstr .= "'".mysql_real_escape_string($lrow) . "',";

}

$lreturn .= rtrim($lstr ,",").");\r\n";

}

mysql_free_result($result);

}

$lreturn .= ("\r\n\r\n\r\n");

}


echo($lreturn);


?>

Thursday 31 January 2008

fedora yum mysql install guide

Here is a basic setup guide for installing mysql on a fedora systemusing the package manager yum.

First thing's first, you need to download and install mysql with the following command;

#> yum install mysql mysql-server mysql-devel

Next, open up your firewall on port 3306 - that's the port external connections (like mysql administrator) use to interact with the database.

#> vi /etc/sysconfig/iptables

Press i (to enter insert mode) and add these lines in an appropriate place;

-A RH-Firewall-1-INPUT -p tcp -m state -m tcp --dport 3306 --state NEW -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m state -m udp --dport 3306 --state NEW -j ACCEPT


Press esc to stop insert mode.
Type :wq

Next restart your firewall for the settings to take effect;

#> service iptables restart

Now navigate to the default mysql-server document directory, and edit the example large confige file for mysql;

#> cd /usr/share/doc/mysql-server-*/
#> vi my-large.cnf

Press esc
Type :w!/etc/my.cnf
Type :q

You have now overwritten your basic configuration file for mysql server. Once you have restarted the mysqld service (using #> service mysqld restart), these settings should now take effect and you should have the mysql service listening on port 3306.

However, you still require a mysql database user who can access the database from an external computer (using mysql administrator) and you also need to set your root password. For the sake of simplicity and to get you connected, i'm going to use the root user in mysql, however I would recomend you use different users to manage your server for security reasons.

Anyway, here's how to set the root password;

#> mysql -u root

use mysql
update user set Password=PASSWORD('yourpassword') where User like '%root%';
quit

Finally, restart the mysql service, for everything to take effect;

#> service mysqld restart

Voila, a workin mysql server which you can connect from external computers to port 3306 on your server.