Simple Debian Squeeze LAMP Config

Want the instant gratification solution?  Scroll down to “All In One” below.

Several of the Linux (Debian Squeeze) / Apache2 / MySQL / PHP (LAMP) configs I’ve seen on the ‘net include complexity you just don’t need (like suEXEC or suPHP).  If you’re setting up a basic server (physical, VPS, Xen, OpenVZ, whatever) and you’re going to be the only person running it, then setting up a LAMP environment is trivial.

This post assumes your server boots and you can log in and that it’s a basic Squeeze install with none of the relevant software pre-installed.  I hate sudo, so I’m going to assume you have either su’d to root (su – root) or that you’ve switched to root via sudo (sudo su – root).  If not, you’ll need to prefix all of these commands with sudo (after setting sudo up).

Although this little guide is for Debian, I think it’ll work unchanged on Ubuntu as well.  This guide also assumes that your server hosts a single website, so nothing fancy with any Apache2 VirtualHosts.

All of the follow steps can be combined, but I like to install by stages so that I can test each element on it’s own, and not get overwhelmed.

One of the big mistakes people new to Debian or Ubuntu do, is they think they have to manually edit config files to get things working.  The Debian packagers spend a lot of time making Debian packages work properly with each other with the absolute minimum manual effort.

Install Apache2

While Apache2 might be a bloated-warthog in the eyes of some system administrators, it’s ubiquitous, reliable, feature rich, well documented and well supported.  You can play with lighttpd, nginx and other options later, but this is LAMP, so let’s install the A.

The default Apache2 install on Debian will try and use the Worker MPM for Apache2.  We want the Prefork MPM when we use PHP5 later, so we’ll specify that straight away.

apt-get install apache2 apache2-mpm-prefork

And that’s it.  Assuming that runs successfully (errors are outside the scope of this walkthrough), you should be able to connect to the web server of your server on port 80 (iptables is also outside the scope of this, but a blank Debian install won’t have any firewalling in the way anyway).

If the install worked, connecting should return a page which says “It works!” and some information about this being the default web page.

Install PHP

Again, PHP gets bad press these days and maybe rightly so, but again it’s well used, well supported and well understood.  It’s probably easier to install it along with Apache2 in reality, because Debian does all the post config work at once then, but if you do it later, you are at least in control of the various stages.

We need to install two things, PHP5 and the Apache2 PHP module (on Debian, this package is libapache2-mod-php).

apt-get install php5 libapache2-mod-php5

and then restart Apache2 (I use the following command, any method that reloads the Apache2 config file works)

/etc/init.d/apache2 restart

That’s it.  You don’t need to edit anything, enable anything, configure anything.  Debian handles all that for you.  The default install of Apache2 creates a /var/www directory which it uses as the root for your web site.  If you go to that directory and create a file called test.php, and put this into it,

<?php phpinfo(); ?>

You can then test the PHP5 install has worked by connecting to your web server and requesting the file test.php.  If it asks you to save it, something went wrong (or you didn’t restart Apache2), otherwise you should get a full list of the PHP settings.

NB: Debian installs Suhosin by default.  This should be okay, but it can cause issues with some features of WordPress and phpMyAdmin.

Install MySQL

The MySQL install is the most complex, because you’ll have to create a password!  Otherwise, it’s as simple as the above steps.  As well as MySQL we need to remember to install the PHP5 MySQL module, otherwise we won’t be able to interact with the database.

apt-get install mysql-server php5-mysql

After some packages are downloaded and installed, you’ll be asked to set a password for the MySQL root user.  The dialog says this is not mandatory.  I think it should be.  You should absolutely set this password.  It does not need to match the Linux root user password, and as in all cases, it should actually differ significantly.

Restart Apache2 for good measure, and you’re done.  MySQL will be started, the relevant libraries are installed, and Apache2 / PHP5 / MySQL can all communicate as required.

By default, MySQL won’t be listening on any external interfaces, which is a good thing, so only your website can communicate with it.  Some guides recommend installing phpMyAdmin at this point, and you can if you want, although I prefer not to.

Permissions

In a default Debian install, Apache2 and PHP5 run as the www-data user.  By default, the permissions on /var/www are

drwxr-xr-x root root

That means the web server can’t create any files or directories in /var/www.  That’s a problem when installing things like WordPress which want to create their own config files or .htaccess files.  Because we’re not worried about multiple users on our server, or different customers, it’s safe to set the owner of /var/www to www-data:www-data, and do the same for all files in that directory.  This advice is only true for a server where you don’t mind all the websites running as the same user, but that’s the point of this example anyway!

All In One

The following command will install the whole thing in one go, and all you need to do is set the MySQL password.

apt-get install apache2 apache2-mpm-prefork php5 libapache2-mod-php5 mysql-server php5-mysql

Follow Up Steps

Later on you might want to install additional PHP modules (such as php5-curl, php5-gd, php5-mcrypt), and for sites which you expect to be busy on servers with not much memory you might want to look at using apache2-mpm-worker and FastCGI.

Stars!

Took this last night while waiting for Bubbles to come in (she didn’t).

No post-processing (other than re-sized to 1024)

Same resized image, but lightened,

And the original full size dark image (won’t display well if you click on it, unless you’ve got a really wide monitor).

An Open Letter to the Cast of Castle

Dear Mr Fillion, Ms Katic, Mr Huertas, Mr Dever, Ms Jones, Ms Quinn, Mr Santiago-Hudson and Ms Sullivan.

Long have I defended the right of artists to have crazy batshit eccentric desires.  It is a fact, I would declare, that actors are artists, and artists have minds that we simple consumers can not understand, can not even fathom.

I have excused the behaviour of artists and actors alike.  Flying a hat first class across Europe?  He’s an artist!  Demanding people not look you in the eye?  She’s an artist!  A bowl of wolf nipple chips in the dressing room?  An artist!

All these and more I have forgiven actors before you and I will forgive actors after you.

But there is a line!

A line that should not be crossed!

Why, I shout now, why do you only work for half a year?  The latest season of Castle has finished its UK run.  Now we must wait!  I am a consumer, I do not wait!  But wait I must for another half year to pass before I see you all on my screen again.

Why?  So you can go gallivanting off and make a movie?  So you can all dress up and go out dancing during the award season?  We consumers work all year!  Every week, earning a crust so we can stuff stuffed crust down our gullets while living our lives vicariously through your on-screen actions.  We can’t cope with you not being there for half a year.  This evening, without Castle on my Television I had to have a conversation with my wife!  My wife!  I’m not even sure what she wanted to talk about, but I’m pretty damn sure I wasn’t interested.

Was it about a woman drowning in a bath of chocolate?  No!  Neither did it involve putrefying corpses lying in bed for a week.  Not even a hint of a crime or a mystery to solve.  Tomorrow I fear I might even need to watch the News or some other non-fiction TV content to get my fix.

So I ask again, what right do you have to only work half a year?  Do I not deserve more than 24 episodes of Castle?  Am I not worthy?

Yours, disgruntled of England.

PS. Keep up the excellent work, looking forward to season 4.

PPS. Wish we could buy the DVD’s in the UK!

Graphing ngIRCd stats (users / servers / channels) with Munin

I run a little ngIRCd server (well two) for some friends to use (if you’re a friend, and you want to know more, mail me!)

I’m also addicted to numbers, and I’m always interested in monitoring the stuff I run, so I’ve written (adapted really) an existing script to track how many users are connected to the ngIRCd daemons using munin.

I’m hosting them on github (along with some other stuff I wrote, or am writing).  If you’re interested, you can check them out (hah, get it? I made a version control joke!) here.

Exim4 (SMTP MTA) + Debian + Masquerading

I love Debian, and Exim4 seems to ‘just work’ for me most of the time, so I tend to use it for my MTA by preference.  Debconf handles the basic options for Exim4 pretty well, and usually I don’t need to mess with anything.

However, on one of my VPS’s I wanted to do what I used to refer to as masquerading.  I use the term to refer to having an SMTP masquerade as a different host on outbound e-mail addresses automatically.  So the server may be fred.example.net, but all outgoing mail comes from user@example.net.  It’s common if you want to handle the return mail via some other route – and for me I do.  My servers are in the darkstorm.co.uk domain, but I don’t want them handling mail for somehostname.darkstorm.co.uk, and I don’t want to have to configure every user with a different address, I just wanted a simple way to get Exim to masquerade.  Additionally, I only want external outbound mail re-writing, mail which is staying on the server should remain untouched.  This allows bob to mail fred on the server, and fred to reply without the mail suddenly going off the server, but if bob mails bill@example.org, then his address is re-written correctly.

I think I spent some time looking at this a couple of years ago, and had the same experience as recently – it’s a bit frustrating tracking down the best place to do it.  Firstly, Exim doesn’t have a masquerade option as such, and the manual doesn’t refer to masquerading in that way.  What it does have is an extensive rewriting section in the config file and support for doing that rewriting in various ways.

On top of this, the Debian configuration of Exim can be a little daunting at first, and how you achieve the configuration may depend on whether you’re using a split config or the combined config.

Anyway, enough rambling, you can get Exim to rewrite outgoing mail / masquerade by setting one macro.  This works on Debian 6 (Squeeze) with Exim4, but I assume it’ll work with Exim4 on any Debian installation.

Create (or edit)

/etc/exim4/exim4.conf.localmacros

Add the following line,

REMOTE_SMTP_HEADERS_REWRITE = *@hostname.example.net ${1}@example.net

Rebuild the Exim config (might not be essential but I do it every time anyway),

update-exim4.conf

and then recycle Exim (reload might work, but I tend to recycle stuff),

/etc/init.d/exim4 restart

That same macro is used for both the single monolithic config file, and the split config file.  It tells Exim that for remote SMTP only, it should rewrite any header that matches the left part of the line with the replacement on the right.  The ${1} on the right matches the * on the left (multiple *’s can be matched with ${1}, ${2}, etc.)

You can supply multiple rules by separating them with colons, such as this,

REMOTE_SMTP_HEADERS_REWRITE = *@hostname.example.net ${1}@example.net : *@hostname ${1}@example.net : *@localhost ${1}@example.net

There are more flags you can provide to the rewrite rules, and you can place rewrites in other locations, but the above will achieve the basic desire of ignoring locally delivered mail, but rewriting all headers on outbound e-mail which match.

Full details of Exim’s rewrite stuff is here.  Details about using Exim4 with Debian can be found in Debian’s Exim4 readme (which you can read online here).

I’m sure there are other ways of achieving this, there’s certainly an option in the debconf config (dc_hide_mailname) which seems hopeful, but it didn’t seem to do anything for me (maybe it only works when you’re using a smart relay?)  Either way, this option does what I wanted, and hey, this is UNIX, there’s always more than one way to skin a cat.

Edit: just had a look at the various Debian package files, and it looks like dc_hide_mailname only works if you’re using a smart relay option for Exim.  If you’re using the full internet host option from Debconf, it never asks you if you want to hide the mailname, and ignores that option when you rebuild the config files.

Too Warm!

It’s pretty warm here atm.  I realised a few weeks ago, that since I record the temperature of a little computer in the house, we can see how the house temperature has changed over time.

The computer does very little, and has roughly the same workload throughout the day, so these temperatures are purely as a result of the ambient air temperature in the room.

CPU’s

Hard Disk

Data collected with Munin and graphed by Munin using the ubiquitous rrdtool.

You are not alone

I was thinking about random stuff last night just (actually, a few days ago now, since it took me a few days to publish this) before falling asleep.  It dawned on me that no matter what our beliefs, there’s a very good chance they’re shared by someone else.  You are truly not alone.  You might feel like you’re the only one who likes something or feels a certain way, or who has experienced a particular thing.  But you’re not.

There’s just under seven billion people on the planet (that’s 7,000,000,000 for clarity, damn you long and short scales).

One Percent (1%)

If you feel like maybe only one in a hundred people feel like you, that’s 70,000,000 (70 million) people.  That’s everyone in the UK and a few more besides.

One Tenth of a Percent (0.1%)

Maybe only one in a thousand people feel like you do.  So that’s 7,000,000 (7 million) people.  So just about everyone in London.

One One-Hundredth of a Percent (0.01%)

If one in ten thousand others have experienced what you have, that’s still 700,000 (7 hundred thousand people the world over).  In other words, everyone in Sheffield.

One One-Thousandth of a Percent (0.001%)

Maybe only one person in every one hundred thousand (100,000) people likes the same band you do.  There’s still 70,000 of you worldwide.  Enough people to fill Old Trafford.

One Ten-Thousandth of a Percent (0.0001%)

Now we’re getting down to small numbers.  If one in a million people think like you, there’s still 7000 of you knocking about the planet.  You could sell out the Hammersmith Apollo and still have to find somewhere to sit the other 2000 people.

One One-Hundred-Thousandth of a Percent (0.00001%)

Maybe you’re one in 10 million.  Maybe no one in all of London feels like you.  Even so, somewhere there are another 699 people in the world who do.  If you got the whole world together in one place, and you asked if anyone felt like you, 699 people would raise their hands.

One One-Millionth of a Percent (0.000001%)

In a land of 100 million people you are unique – but there are still 70 people on the planet who share your interest.  You could hire a London Bus, fill it and tour the world!

Trust me, you’re not alone.

SSH tunnelling made easy (part four)

The first three parts of this series (one, two, three) covered using SSH to tunnel across various combinations of firewalls and other hops in a forward direction.  By that, I mean you are using computer A and you’re trying to get to something on computer B or computer C.  There is another type of problem that SSH tunnels can solve.  What if you’re running a service on computer A but you can’t get to it because your network doesn’t allow any incoming connections?  Maybe it’s a home server behind a NAT router and you can’t / don’t want to poke holes in the firewall?  Maybe you’re in a cafe and no one can connect to your machine because the free wireless doesn’t allow it, but you want to share something on your local web server?

In those situations, you need reverse tunnels (or remote tunnels).  There’s nothing magical about them, they just move traffic in the other direction while still being initiated from the same starting location.

Example 4 – reverse tunnel web server

In this example, we’ll use a reverse web tunnel to enable access to a host for which incoming connections are entirely blocked.  You’re sitting with your laptop in a cafe, doing some work, and you want to show some team mates the new web site layout.  Rather than having to check the code out to a public web server, you can just allow access to the web server you run on your local machine.

The assumption here is that you can SSH into the Shared Server and that your team mate can connect to the SSH server with their web browser.

Your team mate can’t browse to the web server on your laptop, because the cafe firewall quite sensibly gets in the way.  What we need is a way to allow traffic from the SSH server into your laptop.

From your laptop, you create a reverse / remote tunnel (note -R, rather than -L),

ssh -R 203.0.113.34:9090:127.0.0.1:80 fred@203.0.113.34

I’ve used IP addresses in the tunnel so you can see what is going on.  With regular tunnels, the first IP address and port are the local machine.  With reverse tunnels, they are the interface and port on the remote server that are listening for traffic, the second IP address and port are the ones on the local machine to which that traffic is routed.  So our reverse route above connects to the ssh server (203.0.113.34) and starts listening on that network interface (203.0.113.34) port 9090.  Any traffic it gets on that port is routed over the tunnel into 127.0.0.1 port 80 (i.e. your local machine, port 80).

Your team mate can now point their browser at 203.0.113.34:9090 and will actually see the web server on your laptop.  Because you created an outgoing connection through the firewall with the tunnel, the firewall is none-the-wiser, it simply sees regular SSH traffic flowing to and from the SSH server.

In PuTTY the setup would look like this,

The Remote ports option needs to be ticked so that the tunnel will listen to external interfaces on the target machine.

NB: In order to get reverse (or remote) tunnels working in this way, you need to ensure the SSH server to which you connect supports the feature.  For OpenSSH that means you need to enable the ‘Gateway Ports’ open in the sshd_config file.

The Good, The Bad and the Brick Work

A day of two halves.  Our car is dying.  I hate cars.  You know that if you’ve read more than 2 posts on this blog.  I hate them and they hate me.  We can’t afford to buy into owning one at the right level where you can trade them in at the end and get another, so we run them into the ground, end up paying over the odds for maintenance and then manage to scrape together enough money to buy a new one when they die.

So here we are again.

However, in good news, the guy a friend recommended came around today and fixed our brickwork.  Let me tell you, it’s a weight the size of Everest off my shoulders, dampened only by the news of the car (which we got today).

This is how it used to look.

This is how it looks now, with some before and after shots at angles that will make your eyes bleed.