This is my own personal notes on how I set up my new server box. It started out as my notes on how to turn a debian 3.1 Sarge installation into a LAMP box. At the moment it’s a rather detailed dummy’s and/or beginners step-by-step guide to making a LAMP box.
More on what LAMP is at wikepedia
Now Sarge 3.1 is a bit old at the this time, and a new version is just around the corner, but then I’ll learn how to upgrade a debian box when that happens.
I’ll try and be as detailed as possible. I really hate those how-to’s that go “they you press Y,, then N, and then… [do something that might as well be magic, unless you are a guru]”. I’ll try and link to the place where I picked up a bit of knowledge or the idea for doing something.
I’m not a linux wizard. I’ve been running a FreeBSD for a long time, as my webserver, but I can barely keep that alive and malware free. I’ll be trying to set up this box, so that it keep it self up to date and as secure as possible.
Now be aware that this is not the most clever, fast or secure way of doing this – this is just the way that I did it using the bit information that I could find on how to do what I wanted. Some of the stuff that I do is redundant and is redone later. Sometimes several times.
If somebody feels like added comments that tells how things can be done faster, better, more secure I’ll appriciate it and probably incorporate it into the doc.
(feel free to make comments on gramma and spelling – I’ll fix it and then delete your comment. I do appriciate it, it’s just kind of off-topic for the blog)
Installing part 1
My new box: It’s the cheapest machine I could find. AMD Sempron 2600+ with 512Mb of ram and a 80gb harddrive. Nothing special. Everything on the motherboard. It’s four times as fast as the old machine, and has twice the amounts of ram and harddrive space. I’ve it connected to my local home network that connects out to the net through a router. I’ll move it to a “real” connection and server room later, when I’m done getting it to work.
Okay, I download the stable net installation image from this page:
And burn it on a CD.
Okay, pop in the CD.
Turn on the machine.
See it fail because it tries to boot from the empty harddrive.
Press ctrl-alt-del, so that it restarts
Press DEL while it’s restarting, so that I get into the BIOS. Set to boot order to CD first (this varries from BIOS to bios so I whon’t spend time on trying to explain, see you mother board manual..)
It boots on the CD. Wait…
Up comes a screen that asks be to select language, I select English (even though my main language is danish, but if I select that and I need to search for information about something that on the screen, I’ll have to guess at what the original english wording was).
Now it asks Country I in and I select Denmark.
Keymap to use: Danish
Now it detects hardware and network… wait…
Now it asks for a machine name. I’ll call mine… “debian31” – not that original…
Now mine suggests the domain name from my ISP and I accept that… (I’m going to move the machine later, so it isn’t that important. I’m also going to give it a fixed IP address at that time).
More detecting of hardware… wait
Now we get to the harddrive setup. You go two options. Let debian do it or manually edit partion information. I leave it to Debian…
And all files in one partition…
Now it comes up with a suggestion, and I select “Finish partitioning and…”
Now it asks if I REALLTY SURE. I answer Yes (the first time I select something that’s not the default value). NOTE: This will delete everything on your harddrive!
Okay, wait while it prepares the harddrive…
… and installs the basic OS ..
After a while it asks if you want to install a GRUB boot loader. I say Yes.
Now it spits out the CD. Remove it. Select Continue
Now you brand new debian system will boot…
Installing part 2
Wait while it boots.
Now you get a welcome screen – OK.
Now you get a question about timezones – I’m not sure what the clever thing is to do here, so I select the default (no).
Based on my country (denmark) debian asks me if I’m in the Europe/Copenhagen timezone. I select Yes
Root password: “root” is the super-duper, über administrator of a linux machine. You do not want something here that can be guessed. You really should use the random function of a program like keePass to generate (and store) your password. Enter it twice…
Now you should create a new user, that you can use for those times where root is just to much.
For me it’s:
Full name: Thomas Christensen
Password: Again, select something very hard to guess
Now we have to select where to get the rest of the system. As we have a netinstall CD, we have to get the rest from the net somewhere. I select http. The Danish mirror list is suggested, so I select it. Now four alternatives some up. I know the first one is dead, so I select the second one (mirrors.sunsite.dk). I leave the proxy blank.
Wait while it fetches package information.
Now it starts the debian configuration program that can help os install, differnet default package collections. We want a bit more control, so we DO NOT select anything, but simply presses enter to exit the program. It will install a series of very basic packages – this is a good thing, without them the system would be close to useless. If there stuff in there we doesn’t like, we can uninstall it later.
Now wait a while. Enough to go get some coffee.
Mail: The only way a webserver (or any kind of server) can communicate with it’s surrounding is by sending mails. Debian want to know how it should ga about this. As this is a webserver, I select “Internet site” (the first option), for direct SMTP delivery.
Now debian needs to know who to deliver system mail to – it suggest the “tc” user that I created above, which is fine.
And that is it. If we want to run the setup again, we can always start the “base-config” program.
Installing part 3
So, I login as the tc user…
and then I change the user to the root account by typing (from now on all lines that start with #, means that it’s something you have to type, without the ‘>’):
# su -
And entering the root password (you could have logged directly onto the root account, because you are on the machine, but when you connect through ssh, you need to go through a user account and use “su -“, so just to keep the habit, I always do it like that).
So with a bit of help from this google groups thread I do the following (as we just downloaded the package list, some of it isn’t really nessesary). Also, I just use the code from the stable version. Stable is more important to me, than being on the edge.
# apt-get update
It shouldn’t take more that a few seconds.
# apt-get dist-upgrade
Now that shouldn’t take more than a few seconds either, and shouldn’t find any new packages.
Now here’s the interesting part:
# apt-get install apache2 php4 libapache2-mod-php4 mysql-server
Now this installs the A(apache)M(ysql)P(hp) part of our LAMP server (Debian already brings in the L(inux) part) and makes sure that apache knows what to do with php. Now I’ll want more packages later, but I’ll start with this basic bit.
The package system checks for dependencies and tells me that it needs to install 23 packages totally 29.6. Do I want to continue? I type Y and press enter…
Now, something interesting happens to me. At one time during the download part, the machine seems to hang for a bit and when it finish downloading I get a message about a “MD5Sum Mismatch” (an MD5Sum is something that varifies that a download contained excatly what was expected). A suggestion is made to either try apt-get update or try again with –fix-missing.
I ignore that and try again with :
# apt-get install apache2 php4 libapache2-mod-php4 mysql-server
And a get a screen that says, something about remembering to create a hosts entry for the machine name. Besides that the install seems to have gone well. Lets test it. Firstly I need to know the ip-address of my new machine:
This gives a lot of data about the network. The first part of this is my network card – eth0 – which on line two contains the text “inet addr:192.168.0.107 […]”… and looks right for my local net setup. So I type:
So I go to another machine (the one I’m writing this on – you really need another machine standing besides that one you are installing, firstly to make the cd image, but also to look things up). And enter the address “http://192.168.0.107” in the address line of my favourite web-browser (firefox). And get a page like this:
“It worked. Apache webserver has…”
Now the machine will be standing in a server room with no direct access. So I want to install ssh for secure remote administrator.
# apt-get install ssh
Okay, it was already install as part of the base install. Nice.
I fire up my local (on the windows machine, where I’m writing this) copy of putty and type 192.168.0.107 in the address line and after it has created a encryption key set, I get a window like this:
(I’ve made it rather small to make it fit in the format of this blog – normally I make it really big).
I fill in my username, password, type “su -” to login as root and type in the root password, and that gives me:
Isn’t that nice. Now I can remove the screen and keyboard from the machine. And I can do screen shots of the terminal window for this guide. (Just have to hold down Shift-Ctrl-Alt and press the prnt Scrn butten and I have a screenshot of the terminal window that I can paste into a image editor – easy peasy! Standard MS-Windows functionality).
# vi /etc/hosts
This opens up the editor ‘vi’ – it’s one of the more stupid programs in the world, but it’s nearly always there, it’s not as stupid as some, and more importantly I know how to use it.
Now it already contains a line that goes “127.0.0.1 localhost.localdomain localhost debian31” and a few more lines further down in the file (we’ll ignore them).
I add a new line by pressing the [down-arrow key], press [i] (insert mode), type the string “192.168.0.107 debian31” and then press [enter]. Now we have a new line.
Now that I have a machine that I can connect to, I’ll take a break and continue this another day. It’s time and weather for BBQ!
Setting it up
Now it’s the next day and I want to continue the process. So I power up the new machine (now without keyboard and monitor), and try to ssh to 192.168.0.107 (as I did yesterday). No response. Damn. Attach keyboard and monitor and login as root and type
Tells me that it’s running on 192.168.0.105 – so it got a new address from the DHCP server when I started it up. Not really a problem, but I may as well fix that now.
I ssh to 192.168.0.105 and login in as tc and then “su -” my way in as root. No problem. Now what I want is to lock down the ip address. There’s a few ways of doing that – some of them mentioned in this usenet thread from linux.debian.user, I can either do it by hand or user etherconf. I’ll use etherconf. To install it, I type:
# apt-get install etherconf
It will download and install and they run etherconf. If it doesn’t auto-run, start it with
# dpkg-reconfigure etherconf
This will ask you about all your system needs to know about your network setup. The first time you run it, it will ask if you really want to use it. Most of the information it asks about we already provided once, but we’ll do it again. If we later run etherconf again, the values will be pre-filled.
Now how to get the data? As I’m already sitting on a windows box, that can connect to the net and it probably already have the information I need. Running the program “ipconfig /all” (start->run…>cmd[enter]ipconfig /all[enter] (type “exit[enter]” to close window)).
Domain name (I take the “Connection Specific DNS Suffix” from ipconfig, you should use something else, unless you are using TDC in denmark): opasia.dk
<Yes> I want to configure my ethernet card eth0.
<No> it’s not removable, not without a soldering iron.
<No> I don not want to automatically configure with DHCP – that’s why I’m doing this!
Now for an ipaddress – as you can see above, I use the local range 192.168.0.x. DHCP uses everything above 192.168.0.100 and 192.168.0.1 is the gateway. I select a value that I’m sure is unused: 192.168.0.55 – easy to remember.
Broadcast address (the old one when I ran ifconfig on the debian box): 192.168.0.255
DNS Servers (from the “ipconfig /all” information, you should probably use something else): 188.8.131.52 184.108.40.206
That’s it! But now the ssh session dies. That’s because the machine has changed ip-address! I was connected to 192.168.0.105, but the machines name has now changed to 192.168.0.55! Restart ssh and connect again!
Lets see what etherconf did to me hosts file:
That looks fine. I just do a quick cat of /etc/network/interfaces as well and that looks fine to.
Now I got it where I want it! For now – I’m going to go through the same procedure again, when I move the server to the server room, which is on a different net and need other addresses.
The Web Server
Now I want to make sure that the web-server has the feature that I want. I need php, mysql, mod_rewrite (for nice urls), gd (graphics lib), zlip, SimpleXML and WebDav.
If I try to browse to 192.168.0.55 with a webbrowser (from the windows box) I get the “Apache test page”. The easist way to get some information about the webserver and php, is to make a small php script that runs the phpinfo() command. The root of the webserver is /var/www, so I:
# cd /var/www
# vi phpinfo.php
This gives me blank editor windows, so I press i (as in insert), and write the following:
Press [esc] to get out of insert mode and press “:” to get into command mode, now write wq for (Write-Quit) and press enter. Now you have a file called phpinfo.php, so I browse to http://192.168.0.55/phpinfo.php … and it gives me a page with a lot of information about php, apache, etc, etc. Basically this means that apache and php is working. Yeah for me! This is kind of a security risk having something like that laying around on your server, where people can find it. Knowing what version of a library is used on a server, makes it a lot easier to decide how to attack it. I’ll remember to remove it before I let the server go live.
The first block contains an area called “configure command” this tells how php was build for this install. It looks like this:
‘../configure’ ‘–prefix=/usr’ ‘–with-apxs2=/usr/bin/apxs2’ ‘–with-config-file-path=/etc/php4/apache2’ ‘–enable-memory-limit’ ‘–disable-debug’ ‘–with-regex=php’ ‘–disable-rpath’ ‘–disable-static’ ‘–with-pic’ ‘–with-layout=GNU’ ‘–with-pear=/usr/share/php’ ‘–enable-calendar’ ‘–enable-sysvsem’ ‘–enable-sysvshm’ ‘–enable-sysvmsg’ ‘–enable-track-vars’ ‘–enable-trans-sid’ ‘–enable-bcmath’ ‘–with-bz2’ ‘–enable-ctype’ ‘–with-db4’ ‘–with-iconv’ ‘–enable-exif’ ‘–enable-filepro’ ‘–enable-ftp’ ‘–with-gettext’ ‘–enable-mbstring’ ‘–with-pcre-regex=/usr’ ‘–enable-shmop’ ‘–enable-sockets’ ‘–enable-wddx’ ‘–disable-xml’ ‘–with-expat-dir=/usr’ ‘–with-xmlrpc’ ‘–enable-yp’ ‘–with-zlib’ ‘–without-pgsql’ ‘–with-kerberos=/usr’ ‘–with-openssl=/usr’ ‘–with-zip=/usr’ ‘–enable-dbx’ ‘–with-mime-magic=/usr/share/misc/file/magic.mime’ ‘–with-exec-dir=/usr/lib/php4/libexec’ ‘–without-mm’ ‘–without-mysql’ ‘–without-sybase-ct’
The most interesting thing here is the “–without-mysql” part. Hey! I need that. But, before we start trying to install it, search for mysql in the phpinfo page – it may be loaded as an external lib. Okay, it’s missing and so is the gd library (the other stuff that I need is more of an apache thing – more about them later..)
Okay, this phpbuilder page, tells us all we need to know. First we ensure that all the php packages are available (the phpBuilder page has an extra s in the filename – that’s an error).
# vi /etc/apt/sources.list
And insert these two lines (alternativly find lines with address closer to you on the dotdeb mirror page):
deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all
(move to blank line, i for insert mode and either type it all in or paste it in (shift-insert), esc, :wq)
Update the package collection:
# apt-get update
Now lets see what we got, according to phpbuilder we can see that by typing:
# dpkg -l 'php4-*'
Hm, that gives me a few basic php packages and… not all the goodies I was promised.
Okay, so I browse to http://packages.dotdeb.org/dists/sarge/php4/binary-i386/ which is the directory on dotdeb, with the actual packages. It has everything I need and the url to it is in the sources.list file, so I should be able to get to them using apt-get. Firstly I want to encure that I have the latest php4:
# apt-get install libapache-mod-php4
And that actually did a little updating. Just to ensure that apache had the latest version I restart it:
# /etc/init.d/apache2 restart
I refresh the phpinfo page, in my browser and now it says: “PHP Version 4.4.2-0.dotdeb.1”. (the old version was “4.3.something”. Cool.
To install the librarys that I want:
# apt-get install php4-gd php4-mysql
That takes a bit – the gd library is quite big. When it’s done I restart apache again (can’t do that to much), and reload the phpinfo page.
Hm, it still says without-mysql, in the configure-command. I guess that it doesn’t rebuild php.. let search for mysql in the phpinfo page… yes, a bit down, the third enstance of the word “mysql” in my case, there’s a new heading called “mysql” with a bit of info. That should mean that it works. Searching for gd, I find a similar block dedicated to gd. Note: If you, like me, fool around and add and remove these packages a few times, you may have to edit the “Dynamic Extension” part of /etc/php4/apache2/php.ini, as the extension=gd.so and extension=mysql.so, may stay commented out (remove the ;).
Now php has what I want it to have. Lets see if it can connect to the database. I could do that by writing a small script, but as I’ll need the functionality of phpMyAdmin anyway (probably the best way of maintaining a mysql database on a web server), I’ll install that.
I’ll start by seeing if there’s an package that I can install, so I go to: http://www.debian.org/distrib/packages and type “phpmyadmin” in the keyword field and press enter. That gives me one package. “2.6.2-3”- if I go back and set the distribution to search in to unstable, I get the newer “220.127.116.11-1”. Checking on the phpmyadmin page, I see that the latest version is 2.8.1 which contains “a bugfix-only release for the 2.8 family. It also fixes a new vulnerability, see the upcoming security alert PMASA-2006-3”. Okay, it’s nice to have the latest bug fixes, and one shouldn’t run a system with know vulnerabilities… but I do not intend to run phpmyadmin where anybody can get at it anyway, so that’s not a priority for me.
I’ll go with the package from stable (I tried to go with the unstable using the -t unstable parameter on apt-get, but couldn’t get it to work).
# apt-get install phpmyadmin
Firstly it asks which web-server to configure. I select apache2 – and <yes> I want to restart it.
I browse to http://192.168.0.55/phpmyadmin/ and get the phpmyadmin login – now this is a totally unconfigured mysql, taht I’m trying to login to (phpmyadmin uses the mysql users to assign rights), so I login as root and no password. Now notice the red text that tells me that I’m wide open to the world and that I should do something about it. That’s a very, very good idea.
Click on the “Change Password” option. And set a new password (yes, yet another password). I’m willing to compromise a bit here, so I use the same password as the root password for the machine. Click back and the red text has disappeared. Okay, phpmyadmin is running and it’s connecting to the database (or it wouldn’t even have been able to log me in).
Okay, now I just need to configure the apache things. I’ll keep webdav for a later date (I want to use it for a calender, but it’s no hurry), so I just need to install mod_rewrite:
# a2enmod rewrite
# /etc/init.d/apache2 force-reload
So, it’s installed and apache had been restarted – if I reload the phpinfo information, it’s to be found in the Loaded Modules section of the “Apache2handler” block. I’ll test it when I mode the gallery as it’s rather important for that to work nicely.
Reboot, poweroff and halt are all different ways of reboot or turning off your computer, using a commandline command. It wouldn’t work on my new machine. It would close down debian and all services and then just stand there. Now reaching down and pressing the reset (to reboot) or the powerbutton (to turn off) is easy when the machine is standing under your desk. Driving 20 km and signing into a secured datacenter, everytime you have to reboot, is not an option.
A bit of digging around let me to believe that it had something to do with APM. According to the APMd package page, APM is build into the kernal and all you need is to enable it “add this option to your lilo command line”. Now I got no idea if I have lilo commandline… I’m thinking not, as I choose the GRUB loader, and that probably has a commandline as well, but damned if I’m going to spend time figuring it out if I don’t have to …. As always apt-get is the first thing to try:
# apt-get install apmd
and… reboot… and it works.
I did a bit of stress testing of of the web-server and it’s fast. But I wanted to try and install APC, which is a caching mechanism for php. For it to work I need to have the apache development tools installed:
# apt-get install apache-dev php4-dev php-pear
Okay, pear was already installed, but you can’t do it to much. With pear installed, it’s fairly easy to install:
# pecl install apc
# ln -s /usr/bin/apxs2 /usr/bin/apxs
Makes a symbolic link so, that the pecl installer can find the apxs file.
# pecl install apc
Now it works. Take a look at the phpinfo for how apc is setup. Default is 1mb for each running apache demon. Probably fine, for my purposes.
What does it give you? You’ll hear anything numbers 5-500% speed increase – the truth is as always a more varied thing, and depends on what you are running. I tested three different pages in a fairly large phpBB2 setup (30 forums, and 10000 messages) and without APC the server could deliver 15 pages a second. With APC it could deliver 23 pages a second (12 concurrent users, 100mb net, mysql query cache ON, testing using WAST). I’ll try to remember to add a few number on other systems, when I get them installed.
(I later uninstalled APC, with “pecl uninstall apc”, and restart of apache, because it was making gallery2 fail. I’ll probably try eAccelerator later, which is supposed to work with gallery)
Exim is the default mail server – and we selected that earlier when we installed debian. But it doesn’t work out of the box. Run:
# dpkg-reconfigure exim4-config
> <No>, don’t splitt (doesn’t really matter, but searching on one file is earier)
> “internet site…”
> My primary domain is “tc.dk”
> I’ll only send mail from the local machine (no relaying), so: 127.0.0.1
> It says “localhost.localdomain”… I leave that in.
> Make sure that the “domains to relay mail for” and “machines to relay mail for” is blank. We relay for NOBODY! 😉
> Dial up? WTF? <No>
Now send of a mail by typing:
# mail firstname.lastname@example.org
And fill in the mail information – remember to use an email address that works – AND ISN’T MINE! Notice how the mail is ended by writing a single “.” on a line and then [enter].
Bing. A few seconds later I have a message in my inbox from email@example.com.
Lot’s of things run better if the time on the box is correct. Just being able to see the correct date and time in log files can be a life saver. You could login once in a while and set the clock, but there’s a better solution:
# apt-get install ntpdate
This will install the NetTimeProtocol date function which runs once in a while and checks a time server, for the correct time. Lets see what it got:
Lets add it to cron, so that it updates once a day.
# cd /etc/cron.daily
# vi updateclock
And insert the following two lines into the file:
Things covered in part 2
- Secure it (remove stuff, like ftp and phpinfo. Lockdown ssh (ip limited and chroot))
- Make it check for package (security) updates and mail me about it, if there’s anything that should be done.
- Setup Authentication for phpMyAdmin page
Things to do:
- Install webdav
- Make sure that I get status mails (who logged in, etc)
- Find a rss feed with debian security bullitins and add it to my rss reader.
- move it to server room, and reconfigure networking
- install new websites (drupal+events for bornekalenderen.dk)
- move old websites
- Install a news server, just to replicate a few of my favourite usenet groups.