Chapter 5. Guide to Common Ubuntu Servers

While linux has been used as a desktop operating system for a long time, it has arguably been used longer and by many more people as a server. Over the years Linux has accumulated hundreds of different services either ported from another operating system or developed primarily on Linux. This means that when you want to use Ubuntu as a server, there are literally hundreds of different servers Ubuntu could be, many of which can be installed by a simple call to a package manager.

It would be extremely difficult, if not impossible, to document all of Ubuntu’s possible services in a book, much less a chapter. What I realize, though, is that among the hundreds of services you could install, there are a handful of common services that most administrators deal with on a daily basis. This chapter covers some of the most common Ubuntu server types that an administrator will run into. If you are a beginning administrator, I will provide you with a step-by-step guide to set up what might be your first DNS server with some common configuration schemes and best practices. If you are an advanced administrator, think of this chapter as a guide to the Ubuntu approach to servers. I show you how Ubuntu organizes configuration files along with any particular tools or shortcuts it provides for a service. I also cover major file locations so you’ll know exactly where to look for the core configuration files, which init scripts are important, and where logs are stored.

Entire books have been written about how to administer basically every service discussed here. I don’t attempt to document all of the major Apache modules, for instance, nor do I discuss every configuration option for BIND or Postfix. What I give you is a good departure point with working example configuration files. A sysadmin is always busy, so where Ubuntu has provided time-saving shortcuts, I point them out. After all, you only have to do something the hard, “old-school,” time-consuming way so many times before it loses its mystique.

DNS Server

The first service I discuss also happens to be one of the oldest. DNS, or Domain Name System, is one of the fundamental services that keep the Internet running. In a nutshell, DNS is the service that among other things translates a hostname, such as www.ubuntu.com, into an IP address, like 91.189.94.8. DNS servers maintain a local directory of names and IP addresses for which they are authoritative, so that if you ask a DNS server for the IP address for a name for which it is authoritative, it should generally respond with the answer. Many DNS servers can serve recursive requests as well. With a recursive query, a DNS server might not itself contain the record you are looking for, but it can go out on the Internet and find the answer for you.

There are many different programs that provide DNS services on Ubuntu, but the most common has also been around the longest—BIND. BIND, short for Berkeley Internet Name Domain, has many advanced features, but with many features often comes a more complicated configuration file. Honestly, what trips up most administrators is simply building a BIND server from scratch, but as you will see, under Ubuntu the heavy lifting has already been done for you.

Install BIND

There are a few ways to install BIND under Ubuntu. During the initial Ubuntu install you can select DNS Server from the list of server types. If you have already installed Ubuntu, you can type sudo tasksel to get to the same menu. Once you select DNS Server and then OK, the bind9 and bind9-doc packages will automatically be downloaded and installed for you. Alternatively you can just run

$ sudo apt-get install bind9 bind9-doc

What you will discover (and what I cover in more detail next) is that once the Ubuntu BIND package has been installed, you will actually have a fully configured and functioning name server ready, at least, to act as a caching name server for recursive queries. Sample configuration files, root zone files, local zones, and even rndc keys have already been configured for you.

Ubuntu Conventions

There are a few key file conventions that Ubuntu’s BIND uses that might be different from what you are accustomed to, depending on what other Linux distributions you have used. Here are some of the key Ubuntu file locations:

Image /etc/bind/

This directory contains the main BIND configuration file, named.conf, as well as any individual zone files. Any new master zone files should also be stored in this directory or, if you have many zone files you wish to organize, in a subdirectory below /etc/bind.

Image /etc/bind/named.conf

This is BIND’s main configuration file and is where you change BIND’s options and behavior. All of BIND’s individual zone files (files containing name and IP information) are referenced in /etc/bind/named.conf.local. The main options that are enabled in BIND are included from a separate file named /etc/bind/named.conf.options.

Image /etc/bind/db.*

As a convention, all zone files start with db. and then some name or number to identify the particular zone. Names are typically used when the zone contains traditional forward DNS records (names mapped to IPs), and numbers are typically used for reverse DNS records (IPs mapped back to a name). For instance, by default Ubuntu’s BIND will include a few zone files such as db.root (information about the root name servers on the Internet), db.local (localhost zone information), and db.127 (reverse DNS records for localhost).

Image /var/cache/bind

This is BIND’s working directory and where it will store slave zone files. If your server will act as a slave for a particular zone, configure it to store its files here.

Image /etc/init.d/bind9

This is BIND’s init script. Once you install the bind9 package, it will automatically be set up to start on system boot, but you can run the init script manually with /etc/init.d/bind9, or run sudo service bind9.

Image /var/log/syslog

This is the default log file for BIND. A number of different services log to this file, but log entries for BIND will be prefixed by the keyword named, so if you wanted to see only the BIND log entries you could run sudo grep named /var/log/syslog.

Caching Name Server

The default Ubuntu BIND configuration is ready out of the box to be a caching name server. Essentially a caching name server acts as a middleman for DNS queries. Once you configure some hosts to point to a caching name server, when one host requests a particular record, the caching name server goes out to the Internet, retrieves a record, and stores that record locally. If a second host requests the same record, and that record hasn’t expired from the cache, a caching name server will simply return the cached result. This can dramatically improve the response times for a network of hosts, especially for Web browsing, since often the same records (like, say, www.google.com) are requested by multiple hosts.

DNS Master

Caching name servers are very useful, but when most people install BIND, they intend to host some zone files of their own. When a name server hosts zone files locally and doesn’t need to retrieve them from any other source, it is known as a master. When you want to add zones to a DNS server, there are basically three steps: Create a zone file, add a reference to that zone file in named.conf.local, and tell BIND to reload its configuration.

For my example let’s assume that I have a name server inside my network at 192.168.0.5 and I registered example.net. I want this name server to have the following entries:

Image ns1.example.net points to 192.168.0.5 (the name server itself).

Image example.net also points to 192.168.0.7.

Image www.example.net points to 192.168.0.7.

Image gateway.example.net points to 192.168.0.1.

The simplest way to create a new zone file is to copy one you already have and change it. In this case the best candidate is the /etc/bind/ db.local file, so I copy it to db.example.net:

$ sudo cp /etc/bind/db.local /etc/bind/db.example.net

When I open db.example.net in a text editor, I will see the following configuration:

;
; BIND data file for local loopback interface
;
$TTL   604800
@   IN   SOA   localhost. root.localhost. (
                     2        ; Serial
                604800        ; Refresh
                 86400        ; Retry
               2419200        ; Expire
                604800 )      ; Negative Cache TTL
;
@    IN    NS   localhost.
@    IN    A    127.0.0.1
@    IN    AAAA ::1

Because this isn’t intended to be a complete guide to BIND I won’t go into every option in this file, but by default it is configured for a TTL (Time to Live, the amount of time before a name server that has requested a record considers it stale) of 604,800 seconds, or seven days. Next it lists localhost as the SOA (Start of Authority, the server that should be considered the best source of information), and root@localhost is the contact e-mail address to use for this host (referenced by root.localhost). Further down, the file lists localhost as a name server for this zone with an NS record, then sets localhost’s IP address to be 127.0.0.1 and even adds an IPv6 address for localhost with the AAAA record.

I then changed this record to suit the requirements I set out previously, and this is the resulting zone file:

;
; BIND data file for example.net
;
$TTL   1d
@   IN   SOA   ns1.example.net. root.example.net. (
                     2        ; Serial
                604800        ; Refresh
                 86400        ; Retry
               2419200        ; Expire
                604800 )      ; Negative Cache TTL
;
@    IN    NS   ns1.example.net.
@    IN    A    192.168.0.6
ns1  IN    A    192.168.0.5
www  IN    A    192.168.0.7
gateway    IN   A    192.168.0.1

There are a number of things to note in this zone file. For one, I changed the TTL from seven days to one day. While I could have specified it in seconds, BIND supports shorthand, so I can use 1d to mean one day, or 4h to mean four hours. I set ns1.example.net as the SOA and root@example.net as the contact e-mail address. I also set ns1.example.net as the name server to use for this zone, but notice that the NS record references the name of the host. Since this name server is in the same domain, example.net, I needed to make sure I added a record for it here that listed its IP address. Also note that I didn’t need to add .example.net to any of the A records.


Note: Zone Permissions

Be sure once you save your zone file that it has the same permissions and ownership as the other zone files in the directory—that’s the best way to avoid any permission headaches later on once you reload BIND.


Now that I have created the zone file, I need to add a reference to it in named.conf.local. This file doesn’t have any examples to start with, but if you open /etc/bind/named.conf.default-zones with your text editor, you can see a number of similar zone examples such as the one for the db.local file:

zone "localhost" {
   type master;
   file "/etc/bind/db.local";
};

Just add a similar entry to the very bottom of the named.conf.local file:

zone "example.net" {
   type master;
   file "/etc/bind/db.example.net";
};

Once I save my changes, I just need to tell BIND to reload its configuration, and then I should be able to query the name server for one of the new records:

$ sudo service bind9 reload
 * Reloading domain name server... bind           [OK]
$ nslookup www.example.net localhost
Server:         localhost
Address:        127.0.0.1#53

Name:    www.example.net
Address:  192.168.0.7

If the BIND reload fails, it will say so on the command line. If that command-line output doesn’t tell you why BIND refuses to reload, you can view /var/log/syslog for clues.

DNS Slave

A DNS slave is a DNS server that retrieves its zone information from a different DNS server known as its master. In fact, a BIND server can act as a master for one zone and a slave for a different zone. Having a master and one or more slave servers greatly simplifies your DNS administration because you have to update zone information only on the master and it automatically propagates to the slaves. When you update a zone on the master server and increment the serial number inside that zone, once BIND reloads, all of the slaves get notified that the zone has changed and will automatically pull down the updates.

Since a slave DNS server retrieves its zone information from the master, its configuration is much simpler. Provided the master is configured to allow zone transfers from the slave, on the slave you simply have to add an entry to /etc/bind/named.conf.local. For our example, let’s assume I wanted to add a second name server, ns2.example.net at 192.168.0.10.

Configure the Master Server

On my master server, 192.168.0.5, I would need to edit my db.example.net file and add the references to ns2.example .net:

;
; BIND data file for example.net
;
$TTL  1d
@     IN   SOA   ns1.example.net. root.example.net. (
                     3         ; Serial
                 604800        ; Refresh
                  86400        ; Retry
                2419200        ; Expire
                 604800 )      ; Negative Cache TTL
;
@    IN    NS   ns1.example.net.
@    IN    NS   ns2.example.net.
@    IN    A    192.168.0.6
ns1  IN    A    192.168.0.5
ns2  IN    A    192.168.0.10
www  IN    A    192.168.0.7
gateway    IN   A    192.168.0.1

Now I need to add a line to the example.net configuration in named.conf.local so that it allows zone transfers from 192.168.0.10, so example.net’s entry in named.conf.local becomes

zone "example.net" {
    type master;
    file "/etc/bind/db.example.net";
    allow-transfer { 192.168.0.10; };
};

Configure the Slave Server

On the slave server I install the bind9 package either through tasksel or apt-get, and then all I need to do is add a slave entry for example.net at the bottom of /etc/bind/named.conf.local:

zone "example.net" {
    type slave;
    file "/var/cache/bind/db.example.net";
    masters { 192.168.0.5; };
};

Reload BIND with sudo service bind9 reload. Once BIND reloads, it will immediately attempt a zone transfer for example.net from 192.168.0.5. When it completes the zone transfer, if I check the /var/cache/bind/ directory I will see that the db.example.net zone file was created there. Now the next time I want to make a change to db.example.net, I just have to change the file on the master, update the serial number, and then reload BIND on the master. The slave will automatically get the updates.

Manage BIND with rndc

So far I have reloaded BIND with the bind9 init script. Ubuntu includes another tool named rndc that helps you with BIND administration. For instance, to reload the BIND configuration using rndc, I would type

$ sudo rndc reload

You can pass a number of other arguments to rndc to get more information about the BIND service or submit commands to it. One useful aspect of the rndc command is that if you want an administrator to be able to update DNS but not have full root privileges, you can give that person sudo access to the rndc command. If you type rndc with no arguments, you will get a help page that lists the available commands. Here are some of the more interesting ones:

Image reload—reloads all configuration files and zones. If you specify a specific zone after the reload command, it will reload only that zone.

Image retransfer zone—retransfers the zone whether the serial number has been incremented or not.

Image reconfig—like the reload command, except it only reloads named.conf and any new zones.

Image flush—flushes all of a server’s caches. This is handy on a caching name server if it is holding on to a stale IP address that is no longer valid.

Image status—outputs some statistics about the current status of the BIND process, including how many zones it is managing and some statistics on its current workload.

There are numerous resources available if you want more information about BIND configuration file syntax or DNS administration in general. The bind9-doc package includes a series of documentation files under /usr/share/doc/bind9-doc/ that are a great place to start. For instance, to view the first chapter of the BIND version 9 HTML manual, type w3m /usr/share/doc/bind9-doc/arm/Bv9ARM.ch01.html.

Web Server

LAMP is an acronym for Linux Apache MySQL PHP (or sometimes Perl or Python). It refers to the recognition that a very common Web server deployment is a combination of the Apache Web server program using Perl, PHP, or Python for dynamic content and a MySQL database on the back end, all running on Linux. It has become such a common way to set up a Web site under Linux that even Ubuntu has grouped all of the necessary packages together.

The fact is, there are many different approaches to LAMP environments. With high-traffic Web sites often the Web servers run on different hardware from the MySQL database servers. Even if you select the LAMP server option at install, there might be extra Apache modules or other software you also need to install. I will cover MySQL servers in the Database Server section of this chapter, so if you plan to run a full LAMP environment on a single server, be sure to check out that section as well.

Install a Web Server

There are a few different ways to set up a Web server on a default Ubuntu server install. Probably the easiest method is to select LAMP Server during the initial install or afterward with the tasksel tool. This will add the apache2, apache2-mpm-prefork, mysql-server-5.5, mysql-client-5.5, and php5-mysql packages along with all of their libraries and other dependencies. Alternatively you could install each of these packages from the command line with

$ sudo apt-get install apache2 apache2-mpm-prefork \
mysql-server-5.5 mysql-client-5.5 php5-mysql

In either case the package manager will prompt you during the install to enter a root password for MySQL. This is an optional step, but I highly recommend you set the password at this point. For one thing, without a password, anyone on the system can access your databases and change and delete data. Another less technical reason is that it’s simply easier to specify it at this stage than to run extra MySQL commands at the command line. Both the apache2 and mysql init scripts will be configured to start automatically at boot.

Now if your Web site does not use a MySQL back end, or you plan to run MySQL on a separate server, you can skip the mysql-server-5.5 package:

$ sudo apt-get install apache2 apache2-mpm-prefork \
mysql-client-5.5 php5-mysql

Ubuntu Apache Conventions

Like most other distributions, Ubuntu has certain conventions when it comes to Apache administration. Configuration files are organized in a particular way, as are administrative tools and logs. If you aren’t used to the way that Debian and Ubuntu organize Apache, it is quite different from what you may have seen on other distributions. Here are the major file conventions for Apache:

Image /etc/apache2

All Apache configuration files can be found under this directory. Traditionally Apache was configured via one large httpd.conf file containing scores of options, settings, and different virtual hosts. Of course, if you were to simply start with the httpd.conf file here, you would discover that it is empty. Ubuntu has moved away from the monolithic httpd.conf model and has split up its configuration across a number of files and subdirectories.

Image /etc/apache2/apache2.conf

This is the main Apache configuration file used by Ubuntu’s apache2 binary. The default apache2.conf is heavily commented, so it works well as a guide in and of itself to each configuration option and what it does.

Image /etc/apache2/envvars

There are a number of environment variables used by different scripts when Apache starts that define settings like the location of PID files. Those environment variables are defined here.

Image /etc/apache2/ports.conf

This file is used to define which ports Apache listens on when it starts. The default settings have it listen on the standard port 80 and additionally port 443 if the SSL module is enabled.

Image /etc/apache2/conf.d/

This directory is listed as an included directory in the main apache2.conf file, which means that when Apache starts it will also include any configuration files found in this directory and add them to the overall configuration. Some administrators (such as yours truly) have in the past used this directory to store all of their virtual hosts, each separated in its own file, but Ubuntu now has a better solution, which is mentioned later in the chapter. Instead of containing virtual host entries, this directory is used for additional Apache options an administrator (or a package) might want to add separately from the core apache2.conf.

Image /etc/apache2/mods-available/

It always used to be such a pain to add modules to Apache. Once the module itself was installed, you had to dig through a huge httpd.conf file and locate a possibly commented-out reference to include the module and most of the time also had to paste in some sort of IfModule logic as well just to make it load. Ubuntu offers a simpler, more modular approach. All of the modules that are available on the system are represented within this directory by .load and .conf files. The .load files contain all of the configuration necessary to load the modules into Apache, and the optional .conf files contain any extra configuration Apache may need to use the file after it is loaded. If you are wondering what modules you have available for your Apache install, you just need to glance in this directory.

Image /etc/apache2/mods-enabled/

This directory operates much like the different runlevel directories in System V init, so if mods-available is like your init.d directory, this directory is like rcS.d (if you aren’t sure what I mean by that, check out my description of System V init in Chapter 2). Basically this directory contains symlinks to .load and .conf files in the mods-available directory. When Apache starts, it will scan this directory and load all of the modules referenced within. So if I wanted to enable the CGI module, for instance, I could type

$ sudo ln -s /etc/apache2/mod-available/cgi.load \
/etc/apache2/mods-enabled/cgi.load

Of course, Ubuntu even provides tools to simplify that. To enable a module, just run a2enmod followed by the module you want to enable. To enable the CGI module as I did above, I just run

$ sudo a2enmod cgi

Likewise, there is an a2dismod program that will disable a module for you. It takes the same syntax as a2enmod, so to disable CGI type

$ sudo a2dismod cgi

Image /etc/apache2/sites-available/

Ubuntu organizes Apache virtual hosts similarly to modules. Before Apache was created, the available Web server software on the market could host only a single site per physical server. Apache introduced the concept of virtual hosts, which allowed it to host multiple sites on the same physical server. Each virtual host could have a completely different domain name with a completely different document root. Under Ubuntu, each virtual host, or site, that is available to be served by Apache on this machine has its configuration in a separate file under sites-available. By default the only file in there is the aptly named default file that defines the default virtual host that will show up if no others are configured, or if no other site’s configuration matches the hostname that is requested.

Image /etc/apache2/sites-enabled/

Like mods-enabled, this directory contains symlinks to configuration files in sites-available. So when you want to add a new virtual host to Apache, just create a new configuration file for that host that contains a complete <VirtualHost> block under sites-available and symlink it here:

$ sudo ln -s /etc/apache2/sites-available/mysite \
/etc/apache2/sites-enabled/mysite

Or you can use the a2ensite script that works just like a2enmod. Just run a2enmod with the site you wish to enable as an argument. To enable mysite I would type

$ sudo a2ensite mysite

and to disable it I can use a2dissite:

$ sudo a2dissite mysite

The default site is a special case in that it prepends 000 to its symlink under sites-enabled to make sure that it loads first and works properly as the default virtual host.

Image /var/www/

This is the default document root for Apache. Any HTML file that is readable by Apache and placed in this directory will be available once you point a Web browser at the server. There is already a default index.html in that directory.

Image /usr/lib/cgi-bin/

This is the default location for CGI scripts. Any scripts referenced on the Web server by /cgi-bin will point here.

Image /var/log/apache2/

This is the standard directory where Apache logs are stored. The access.log file contains information about what files have been accessed on the Web server, and the error.log file lists any Apache errors. If, for instance, you have trouble starting Apache, look in error.log for clues.

apache2ctl

The /usr/sbin/apache2ctl program is the primary command-line program you will use to manage Apache under Ubuntu. The syntax for the command is fairly straightforward. Run apache2ctl from the command line and pass a single command to it as an argument. The simple commands start, stop, and restart will, as you might imagine, start, stop, and restart the Apache process respectively. You could also achieve the same functionality with the apache2 init script, so three commands that do the same thing are

$ sudo apache2ctl restart
$ sudo /etc/init.d/apache2 restart
$ sudo service apache2 restart

Stop Apache Gracefully

There is a potential risk associated with the restart and stop commands. When you restart or stop Apache with these commands, all currently running Apache processes are killed, even if they are in the middle of serving files to a user. If you issue a restart when a user is in the middle of loading a page, it will only load as much information as it currently has and then stall—forcing the user to reload the page. To avoid this, apache2ctl has provided the graceful and graceful-stop commands. These commands respectively restart and stop Apache, but when they do, they wait for each process to finish any outstanding requests first. On an active site a graceful restart shouldn’t even be noticed by anyone using the service. In general, unless you know that a site is not actively serving traffic (or unless you don’t care whether all active connections are closed), you should use graceful and graceful-stop. The only exception is when you add new SSL certificates to a site or make other changes that do require a full Apache restart to take effect.

Diagnostic apache2ctl Commands

The other main commands for apache2ctl provide more diagnostic features. The first, configtest, will test your current Apache configuration files for errors. This can be very useful if you decide to automate the deployment of your Apache scripts. One challenge when you set up a script to deploy configuration files and restart Apache is that if you have made a mistake in your configuration files, Apache might not start back up. If you deploy the same file to your entire Web farm, you could potentially bring the entire farm down with a single syntax error and a script that blindly deploys and restarts Apache. With configtest, you can set up logic in your deployment scripts that restarts Apache only once a server has passed the configtest.

As an Apache server gets traffic, you typically want to get diagnostic information from it, such as how many Apache processes are active and what those processes are doing, and how many open slots you still have available. The status and fullstatus apache2ctl commands provide you with a lot of great diagnostic data. The status command outputs a general-purpose overall status of your Apache server, including how long the server has been up, how many requests are active, and how many processes are idle, and in addition outputs an ASCII art map of all available processes with different letters representing different process states, as shown in Figure 5-1. The fullstatus command outputs similar information, just more of it and in more detail.

Image

Figure 5-1 apache2ctl status output

Apache Documentation

While this guide is good enough to get you started, as you develop complicated Web sites of your own, you will need more complete Apache documentation. Entire books have been written about Apache configuration, but you can also get great documentation directly from your Ubuntu server. Just install the apache2-doc package:

$ sudo apt-get install apache2-doc

This package installs the Apache documentation under /usr/share/doc/ apache2-doc/manual in HTML files. You could use w3m on these files directly, but why not use your desktop’s Web browser instead? The default Apache virtual host is configured to point to this directory for you. Just browse to the /manual/ folder on your Web server. For example, if my Web server were at 192.168.0.5, I could go to http://192.168.0.5/manual/ in a Web browser and view the complete documentation.

WordPress, a Sample LAMP Environment

There are any number of different Web sites you can set up on an Ubuntu LAMP stack, but to illustrate how easy it is to set up a new site under Ubuntu, I walk you step by step through a common LAMP deployment—a WordPress install. WordPress is popular blogging software that is packaged by Ubuntu and provides a nice, feature-rich platform for one or multiple blogs.

Install WordPress

In this example I run both the Web server and the MySQL database on the same host, named blog.example.net, so I chose the LAMP Server task during the install. I’ve also already made sure that blog.example.net is set up in my DNS server to point to this particular Web server. Next I use a package manager to install the WordPress package, which will pull down the WordPress software along with any extra libraries it needs:

$ sudo apt-get install wordpress

Configure Apache

There are a few different ways you can configure Apache for use with WordPress, and the included example Apache file at /usr/share/ doc/wordpress/example/apache.conf provides the main options you are looking for. The first example in the file provides the best all-around case because it makes it easy to host multiple WordPress blogs on the same site. Save the following configuration under /etc/apache2/sites-available/wordpress:

NameVirtualHost *:80

<VirtualHost *:80>
UseCanonicalName    Off
VirtualDocumentRoot /var/www/%0
Options All
</VirtualHost>

With the configuration file in place I use a2ensite to enable the site and a2dissite to disable any default sites that might be there:

$ sudo a2ensite wordpress
$ sudo a2dissite default

Since the configuration uses the VirtualDocumentRoot option, I need to make sure that the vhost_alias module is enabled, so I use the a2enmod command:

$ sudo a2enmod vhost_alias


Tip

How did I know that VirtualDocumentRoot needed the vhost_alias module? Well, for one thing, if you try to reload Apache without the module, Apache will complain about the unknown configuration option. At that point a quick Web search on Virtual -DocumentRoot will point you to the vhost_alias module as the one that provides that feature.


Now I need to create a symlink for my Web site under /var/www and point it to the root WordPress directory that contains all of the PHP files. If I wanted to host multiple WordPress sites, I could potentially create multiple symlinks here.

$ sudo ln -s /usr/share/wordpress /var/www/blog.example.net

Now I can reload Apache:

$ sudo apache2ctl graceful

Configure MySQL

WordPress provides a simple script under /usr/share/ doc/wordpress/examples/setup-mysql that will set up a WordPress MySQL configuration for the specified MySQL user and domain name for the Web site:

$ sudo bash /usr/share/doc/wordpress/examples/setup-mysql \
-n wordpress blog.example.net

That’s it. The blog is ready to be used. All I need to do at this point is open http://blog.example.net in a Web browser and I will be greeted with the WordPress install Web page as shown in Figure 5-2. The final step is to enter your site name and e-mail address in the fields provided and click the large button that says Install WordPress. The database will then be set up for your site and a new page will load that lists your admin username and temporary password as well as a link to log in to your blog. At this point the rest of the configuration is up to you. You can change themes, create a Hello World post, install plug-ins, or, even better, change your password to something you can remember.

Image

Figure 5-2 WordPress Web install page

Mail Server

Along with the Web, e-mail is probably the service most people think of when they think of the Internet. Like Web servers, mail servers have traditionally been pretty tricky to set up, and there are many guides and books on the subject. You will find, though, that mail servers are pretty easy to set up and use under Ubuntu. Now there are a number of different mail servers one can choose from, but for this section I am going to discuss Postfix. For one reason, it is the default mail server Ubuntu uses when you select “Mail server” in tasksel. Second, it is a good, secure, easy-to-administer mail server.

Install Postfix

Postfix can be installed with the same methods used by many of the other services I mention in this chapter. You can choose Mail Server either during the initial install or when you run the tasksel program, or alternatively you can type

$ sudo apt-get install postfix

When you install Postfix, the installer will start the initial Postfix configuration script. This is an interactive script that provides you with a few common mail server configuration types, and depending on what you choose, it will ask you a few more questions so that when you are finished, you should at least have a functional mail server. Keep in mind, though, that even though the mail server will function, you will have to perform extra configuration if you want to add spam checking, greylisting, POP or IMAP servers, or other more advanced options.

Postfix Configuration Types

If this is your first exposure to a Postfix mail server configuration, you might not be sure exactly which mail server configuration type to choose. Here are the different configuration types along with why you might want to choose them:

Image No configuration

This option does no Postfix configuration at all. Choose this option if you already have a Postfix configuration file you want to add, or if you want to build the configuration file from scratch.

Image Internet site

This option creates a basic mail server that can receive incoming mail directly from the Internet and also can send e-mail directly to other mail servers on the Internet. Choose this option if you need a basic mail server, and this server will not be prohibited (by firewall or other network configuration) from sending and receiving e-mail over the Internet.

Image Internet with smarthost

This option is a lot like the Internet site except that all outgoing e-mail is sent via a smarthost. A smarthost is another e-mail server that acts as a sort of proxy for e-mail. Organizations often use a smarthost so that they have a single e-mail server that has outbound e-mail access. This way they can centralize outbound spam and virus scans and can firewall off the rest of the e-mail servers from directly sending e-mail over the Internet. Don’t forget to confirm that the smarthost is configured to accept e-mail from this new server.

Image Satellite system

This configuration option forwards both outgoing and incoming mail through a smarthost. You might select this option if you want to provide mail server redundancy. Your smarthost could be the ultimate destination for e-mail and could act to send out all outbound mail, but your satellite system could be your primary, secondary, or tertiary mail server that can help offset the load from your smarthost.

Image Local only

If you choose this option, this server will deliver only local mail such as e-mail sent to root from cron processes or other e-mail sent to a local user from another local user. The server will not accept any mail from the network. Choose this option if you want to use Postfix as your local mail server but don’t intend to send or accept any e-mail from the rest of the network.

Depending on which configuration you choose for Postfix, you will be prompted to select a hostname the mail server will use for outgoing mail. This may or may not be the same as your server’s hostname. This is the hostname that Postfix will use to label outgoing e-mail. So, for instance, if you named your server zeus internally, but on the Internet the host will be referred to as mail2.example.com, then you would put mail2.example.com in this field.

Ubuntu Postfix Conventions

There aren’t too many surprises with Ubuntu’s Postfix conventions, but the following are the major directories and files used by Postfix under Ubuntu:

Image /etc/postfix/

This directory contains all of the major Postfix configurations. Of course, programs that work with Postfix, like spam filters and greylisting software, will typically store their configuration elsewhere.

Image /etc/postfix/main.cf

This is the main Postfix configuration file. The upstream main.cf is heavily commented and lists all of the major options, their defaults, and nice descriptions. It’s great when you want to learn about Postfix, but it can be cumbersome to actually use as a configuration file. Because of this, the Ubuntu install script for the Postfix package generates its own smaller main.cf file, although you can still reference the fully commented version at /usr/share/postfix/main.cf.dist.

Image /etc/aliases

This file contains a mapping of user aliases Postfix will reference for mail delivery. The basic syntax is essentially username1: username2, which tells Postfix to redirect mail addressed to username1 to username2. You can also redirect mail to piped commands to do more sophisticated redirection.

Image /var/spool/mail/

This directory by default contains the mailboxes for each user on the system. By default Postfix will use the mbox format, so every e-mail for a user will be in a single file under this directory named after the user. This, of course, could change if you install POP or IMAP servers or store mail in Maildirs instead, but more on that in the POP/IMAP section of the chapter.

Image /var/spool/postfix/

Postfix stores many different subdirectories within this directory and uses them to organize mail that is being spooled by the system either for delivery on the server or delivery to a different mail server. Generally speaking, you won’t want to meddle in this directory. Postfix provides tools you can use to get information on the current mail spool.

Image /var/log/mail.*

Postfix logs are organized into a few different log files under Ubuntu so you can more easily find the information you need. The mail.log file stores all mail logs, so if you aren’t sure what other logs to check (or are going to just use grep to find the information you need anyway), use this log file. Similarly, the mail.info log contains all of the informational logs such as new mail that has been queued, log entries for each transaction with a remote server, and other common log entries. The mail.err and mail.warn files segregate out errors or warnings from the rest of the Postfix logs, respectively, so look here if you want a quick view of errors or warnings.

Image /etc/init.d/postfix

This is Postfix’s init script and should automatically be set up to start at system start-up.

Administering Postfix

The main tool you will use to administer Postfix is aptly named postfix. It works much like apache2ctl in that it accepts a few different commands as arguments and can also be used as a substitute for the init script to start and stop the service. For instance, to stop Postfix and then start it back up, you would type

$ sudo postfix stop
$ sudo postfix start

The other commands generally work the same way. Here are the major commands you can pass to Postfix along with their functions:

Image reload

Use this command whenever you have made changes to the Postfix configuration and want to load it. This operates much like the apache2ctl graceful function in that it allows each process to terminate and reload when it can, so it is much safer and provides a much smoother process than if you were to stop and then start Postfix.

Image flush

This command tells Postfix to flush its mail queue. Typically Postfix spaces out its mail delivery so as not to throttle the network, and when a message gets deferred for some reason, it will be delayed in the queue for some time before Postfix attempts redelivery. Sometimes you will have some issue, such as a network outage, that causes a large number of e-mails to spool on the server, and once the problem is remedied you would like to deliver them. When you use the flush command, Postfix forces delivery of all of the deferred messages immediately. Generally speaking, you should let Postfix spool and deliver messages on its own schedule, so use this command only if you really need it.

Image status

Returns the current Postfix status. If Postfix is running, this command also returns the PID of the master process.

Image abort

This is a more forceful version of the stop command and immediately kills all running Postfix processes whether they are finished or not.

Image check

This command is much like apache2ctl check. It scans the Postfix directory structure for bad file or directory permissions and warns you about and corrects any problems it finds.

In addition to the Postfix command-line tool, Postfix provides a few other tools to help administration of the service. The postqueue command can be used by regular users to get information about the current mail queue. This is useful so that you can keep track of deferred messages and answer the “I sent this e-mail two hours ago and the recipient said they didn’t get it. What happened?” questions. For instance, to get a full listing of all messages currently in the queue, type

$ postqueue -p

Sometimes you want to take action on messages in the queue besides simply flushing them. Occasionally you might want to delete a message (or maybe even all messages) in the queue. The postsuper command allows a superuser to perform privileged operations on the queue. For instance, to delete a message in the queue with a queue ID of 522, you would type

$ sudo postsuper -d 522

If you actually did want to delete all messages in the queue, you can use the word ALL in uppercase instead of a particular queue ID. You might also want to put a message on hold so that Postfix keeps it in the queue but doesn’t attempt to deliver it. Use the -h option followed by the queue ID to put a message on hold and then use the -H option with the same queue ID to put the message back in the queue.

Previously I discussed the /etc/alias file and how it is used to map one username to another for mail delivery. The /etc/alias file is actually just for humans to edit. Postfix doesn’t directly read it. Instead, it creates a database out of that file that it can reference much more quickly. Whenever you edit that file, type sudo newaliases to update the /etc/alias.db file. In addition, for some more advanced Postfix configuration such as canonical maps, virtual accounts, or other features, you will have a separate file within /etc/postfix that also needs a database. You can identify these files in the main.cf file as their paths are preceded by hash:. If you do create or edit one of these lookup tables, run sudo postmap /path/to/file. If I set up virtual users in /etc/postfix/virtual, I would update the database with

$ sudo postmap /etc/postfix/virtual

Finally, there are occasions when you are tweaking your main.cf file and want to see what the current and active setting is on the running instance of Postfix. The postconf command outputs every (and I mean every) Post-fix setting to the screen along with its value. So if I wanted to see the current value of myhostname in the running config, I could type

$ sudo postconf | grep ^myhostname
myhostname = mail1.example.net

Default Postfix Example

One of the great things about the Postfix install script is that once you have completed it, you should have a functioning mail server. Of course, depending on how you plan to use the server, there might still be more configuration to do. While there is almost infinite tuning and tweaking you can perform with Postfix, there are a number of common configuration options you will want to look into. I cover some of the major options and then provide a few examples of different mail server configurations.

For all of these examples, I start with a basic main.cf file for an Internet site set up by the Postfix install script. This configuration accepts mail from the local network as well as mail sent to example.org and mail1.example.org. Here is the full main.cf file:

# See /usr/share/postfix/main.cf.dist for a commented, more
complete version


# Debian specific:  Specifying a filename will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database =
btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database =
btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc
# package for information on enabling SSL in the smtp client.

myhostname = mail1.example.org
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = mail1.example.org, example.org,
localhost.example.org, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

The beginning of the file mostly sets Ubuntu defaults that differ from standard Postfix defaults. The core configuration for you to tweak starts at myhostname. To get full documentation on each of these options, type man 5 postconf. That manual contains all of the Postfix configuration options along with a description of their use. Here are a few of the options in the sample configuration file that you will use frequently:

Image myhostname

This is the Internet hostname of the mail server. If you haven’t set it explicitly in this file, it will use gethostname() and use that value. A number of other options, such as myorigin, will use or reference the myhostname value if it isn’t explicitly set.

Image myorigin

The domain name listed here is the domain that mail sent from this machine appears to come from. If, for instance, your server is named mail1.example.org but you want e-mail sent from it to appear to come from example.org, you would set this value to example.org.

Image mydestination

This is a list of domain names for which this mail server will accept mail and consider itself the final destination. If mail arrives on this server addressed to one of these domains, Postfix will deliver it locally.

Image relayhost

In this example this value is blank, but if you did want to route all of your outbound mail through a different mail server, you would set this value to the hostname of that server. You might use this value on all of your servers in a data center so they all point to a single outbound mail host. You could then more tightly control firewall access and have a single choke point from which to view all outbound messages.

Image mynetworks

This value is a comma-separated list of networks (IP addresses and subnet masks) for which this server will relay mail. Be very careful with this value! If you were to set this to too broad a value and allow random hosts on the Internet to relay through your server, you will have just set up what’s known as an open relay. Open relays are often used by spammers to relay their spam, and if you mistakenly make your server an open relay it won’t take long for someone to discover it and for your server to be put on a spam blackhole list. Generally speaking, this will be set to localhost and possibly your internal network interface if you want to allow other hosts on your network to relay mail through you.

Image mailbox_size_limit

This option sets the maximum value of any local user’s mailbox. The default in this example sets it to unlimited.

Secondary Mail Server

The default example I gave will work fine as a default Internet mail server for a small domain, such as your own personal mail server. Once you set up a mail server that accepts messages for a domain and you start to rely on it, you should consider setting up a secondary mail server to act as a backup. If you have only one mail server and it goes down for some reason, any host that wants to deliver mail to it will ideally queue the messages for a few days. If the server does not come back up in a set amount of time, though, the messages will bounce back to the sender as undeliverable. Each administrator might set up his or her mail server to bounce after a different period of time. Postfix by default will set this to five days via the bounce_queue_lifetime option.

To avoid bounced messages, you will want to set up at least one additional mail server that can accept and spool mail for your domain. This server will then deliver the messages to the primary mail server once it is back up.

It’s actually pretty easy to set up a secondary mail server with Ubuntu and Postfix. We start with the Internet site install-time option which gives you a main.cf much like the one I listed earlier. At this point the only other option you really need to add to the main.cf is the relay_ domains option. This option defines the domains for which this machine will accept and relay mail. So, for instance, if you wanted to set up a secondary mail server for example.org and example.net, you would set this value to

relay_domains = example.org, example.net

Once you reload this configuration with postfix reload, all you need to do to start using the secondary mail server is to add an MX record to your domain’s DNS zone and be sure that its priority number is larger than the primary mail server’s. If my primary mail server is mail1.example.org and the secondary is mail2.example.org, the zone entries might look like the following:

example.org.   IN      MX      100       mail1.example.org.
example.org.   IN      MX      200       mail2.example.org.

Once the DNS changes have propagated, your mail server will start to be used. One final setting you may want to consider for your secondary mail server is an increase in the number of days it will queue mail before it bounces. If you know that a primary mail server will be down for more than five days, you might want to increase the limit so that the secondary mail server will still hold mail for you until the primary mail server comes back online. To increase the queue limit to two weeks, for instance, add the following settings to your /etc/postfix/main.cf:

bounce_queue_lifetime = 14d
maximal_queue_lifetime = 14d

Once the primary server does come back online, run postfix flush on the secondary server so that it immediately starts delivering all of the deferred messages.

Greylisting Mail Server

Spam is a definite problem for just about every mail server administrator. There are many solutions out there to help cut down on the amount of spam a server receives, and one such concept is known as greylisting.

Greylisting is based on the notion that since spammers send out millions of e-mails, they generally don’t set up a deferred queue if an e-mail is not immediately delivered. There is a special response in the SMTP protocol called 450 that basically says, “Please come back later.” Most legitimate mail servers on the Internet will honor that request and come back later. Most spammers won’t. With greylisting, your mail server will respond to all new mail servers with a 450 command. Once a server does come back, the greylisting program makes a note of it in a local database of servers, To:, and From: addresses. That means (depending on how many successes you configured before a server is whitelisted) that after a server waits once, it won’t have to wait anymore in the future.

There are a number of different programs that implement greylisting for Ubuntu, but one of the simplest to set up with Postfix is called Postgrey. It implements greylisting as I mentioned earlier and also includes whitelists for major mail servers that are known to not work well with greylisting; it also allows you to whitelist servers so that they never see the initial delay.

Install and Configure Postgrey

To install Postgrey, use your package manager to install the package of the same name:

$ sudo apt-get install postgrey

The Postgrey program is started via an init script at start-up and listens on the local 10023 port for queries from Postfix. Once it is installed and running, all you need to do is modify the smtpd_recipient_restrictions option in Postfix’s main.cf to add the localhost:10023 service. If you haven’t tweaked your smtpd_recipient_restrictions setting at all, here’s a sample that should work for you:

smtpd_recipient_restrictions = permit_mynetworks, \
           permit_sasl_authenticated, \
           reject_unauth_destination, \
           check_policy_service inet:127.0.0.1:10023

Once you add that option, reload Postfix and it will start implementing greylisting immediately. If you aren’t too familiar with greylisting, then this should work well for you to start. If you do wish to tweak the whitelists, for instance, the default Postgrey configuration is stored under /etc/postgrey. The whitelist_clients and whitelist_recipients are provided by the Postgrey package and have some good defaults set. If you would like to add additional entries, create a whitelist_clients.local or whitelist_ recipients .local file so you can keep your settings separated. Then type sudo service postgrey reload so Postgrey will reload its settings. If you would like more specific information on configuration file syntax or other Postgrey options, check out the documentation under /usr/share/doc/postgrey/.

POP/IMAP Server

Most people who set up mail servers no longer actually log in to the mail server to retrieve the mail. They generally use some sort of mail client that then connects to some destination mail server and retrieves mail via POP or IMAP. With POP, the messages are downloaded and removed from the server as you access them, whereas with IMAP the messages continue to be stored on the server. Ultimately it’s good to provide both as options, but these days most people prefer IMAP so they can connect to the mail server from multiple clients and still see all of their mail.

There are a number of different packages that provide POP and IMAP support, and choosing one is at least partially a matter of preference. For this example I cover the Dovecot POP and IMAP servers, as they integrate well with Postfix, support Maildirs, and have a number of additional packages available that provide more advanced features such as LDAP, MySQL, and Postgres support. The steps are pretty simple. They start with enabling Maildirs on Postfix, then installing Dovecot.

Enable Maildirs on Postfix

There are a number of different ways that mail servers can store e-mails. For a long time the primary format for mail storage was the mbox format. With the mbox format, all of a user’s mail is stored in a single large text file. This method works; however, it’s not without its shortcomings. For one, with an mbox all of your eggs are in one basket. If that file is corrupted, so are all of your e-mails.

Nowadays in addition to the mbox format mail is often stored in databases (Exchange) or in a Maildir. A Maildir basically breaks up each e-mail folder into its own directory on a host. Within that directory are subdirectories to store new and read e-mail. Within those subdirectories each e-mail is stored as its own text file. The nice thing about Maildirs is that there is already a large number of tools on any Linux system to parse through and manage files, making it simple to find an individual e-mail on the system and back it up, delete it, or copy it.

To enable Maildirs under Postfix, you just need to set the home_mailbox option to specify the directory name you will use for your Maildirs. Open /etc/postfix/main.cf and add the following option:

home_mailbox = Maildir/

Be sure to remember the trailing / after the directory name, as it is needed when you use Maildirs. In this example Postfix will use the Maildir directory in each person’s home directory to store e-mail. Once you have made the change, type sudo postfix reload to reload the configuration. At this point all new e-mail will be delivered to the Maildir directory in the local user’s home directory. If the directory doesn’t exist, Postfix will create it.

Install Dovecot

All of the Dovecot packages you need are available by default in Ubuntu. If you installed Postfix during the install or afterwards with tasksel, the Dovecot packages are included. Otherwise, you can just use your package manager to install them. The packages I will install will enable POP, POP with SSL, IMAP, and IMAP with SSL:

$ sudo apt-get install dovecot-imapd dovecot-pop3d

By default Dovecot will be set up for POP, POP with SSL, IMAP, and IMAP with SSL. If for some reason you want to disable any of these options, open Dovecot’s default configuration file, /etc/dovecot/dovecot.conf, and locate the line that says

protocols = imap imaps pop3 pop3s

Just remove any of the protocols you don’t want enabled and run sudo /etc/init.d/dovecot reload to enable the changes. The next step is to tell Dovecot to use Maildirs and also let it know where it can find them on the system. To do this, see if there is already an uncommented line that starts with mail_location (in the default install it’s commented out). If it doesn’t exist, then add the following line; if it does exist, then modify the mail_location line so that it looks like the following:

mail_location = maildir:~/Maildir

Then reload Dovecot with sudo /etc/init.d/dovecot reload. Now you should be able to configure your mail clients to point to the server and access their local mail.


Note: Allow Plain Text Authentication

By default Dovecot is configured to use the system’s local accounts. Note, however, that it will allow you to use plain-text authentication only if you do so over a secure protocol like IMAPS or POP3S. If you want to use IMAP or POP3 with plain-text passwords and don’t have a problem with user passwords being transmitted over the wire unencrypted, then set the configuration option disable_plaintext_auth in dovecot.conf to no:

disable_plaintext_auth = no

then reload Dovecot so it takes the new changes.


Ubuntu Dovecot Conventions

Dovecot follows fairly standard conventions for where it stores its files. This section describes the common files and directories Dovecot uses:

Image /etc/dovecot/

This is the default configuration directory for Dovecot and contains all of the configuration files, including dovecot.conf, the main file you will use to configure the service.

Image /etc/init.d/dovecot

This is Dovecot’s init script. The script is set up at install time to automatically start at system start-up.

Image /var/log/syslog and /var/log/mail.log

Dovecot sends copies of its logs to both of these files so you can use either to look for errors or monitor logins.

OpenSSH Server

While I can understand why this service is not installed by default, most system administrators these days use SSH to remotely manage their servers. SSH provides you with a secure encrypted channel so that you can log in and execute commands on a remote machine. In addition to the standard remote console uses, SSH also allows a number of interesting hacks so that you can set up tunnels, run remote X applications, and do all sorts of other interesting tricks. It seems an article on a new SSH trick shows up online every few days.

To install OpenSSH, you can either select OpenSSH Server during the task selection process in the installer, run sudo tasksel after the install and select it there, or run

$ sudo apt-get install openssh-server

Once the package is installed, the sshd process will start. To log in to the server from a remote host, type

$ ssh username@hostname

Replace username and hostname with your username on the machine and the hostname or IP address of the machine, respectively. Once you log in over SSH, you can run commands on the remote server as though you were on the machine with a keyboard and mouse. To log out of a current SSH session, just type exit in the terminal.

Ubuntu OpenSSH Conventions

This section describes the major directories and file locations for OpenSSH along with their use:

Image /etc/ssh/

This directory contains all of the major configuration files for both the OpenSSH server and the client.

Image /etc/ssh/ssh_config

This file defines the default client settings for SSH clients on this machine. Local users can override these options with their own options in ~/.ssh/config.

Image /etc/ssh/sshd_config

In this file you will find the default settings for the SSH server. It’s worth noting that by default root logins over SSH are enabled, even though Ubuntu doesn’t set up root logins on the system itself by default. If you want to disable root logins, edit the file and set the PermitRootLogin value to no.

Image /etc/ssh/ssh_host_dsa_key and /etc/ssh/ssh_host_dsa_key.pub

These files provide the private and public DSA keys for the system, respectively. These keys are used to authenticate the system so that you can better detect man-in-the-middle attacks.

Image /etc/ssh/ssh_host_rsa and /etc/ssh/ssh_host_rsa.pub

These files are like the DSA keys I mentioned earlier, only they are created using the RSA algorithm instead.

Image /etc/init.d/ssh

This is the init script for the OpenSSH server and provides the standard start, stop, and restart commands as well as reload and force-reload commands for when you change its configuration files.

Image /var/log/auth.log

The OpenSSH server will log its information to this log file, including informational messages, errors, and user logins.

DHCP Server

It’s easy to take DHCP for granted these days. After all, even the most basic home wireless routers seem to provide a DHCP server as part of the firmware, and most corporate networks seem to use DHCP, at least for desktops. If you’ve ever had to administer a large network of desktop machines without DHCP, though, you probably recall the pain of manually entering static IP information into Windows desktop after Windows desktop.

DHCP stands for Dynamic Host Control Protocol, and with this protocol a new host on the network can issue a request for IP information. The DHCP server will then provide the host with all of the necessary information it needs to communicate on the network, such as its IP address and netmask and the gateway and DNS servers to use.

Install DHCP

To install a DHCP server under Ubuntu, type

$ sudo apt-get install dhcp3-server

Ubuntu DHCP Conventions

This section describes the major directories and file locations for DHCP configuration along with their use. Note that in prior versions the configuration files were stored in /etc/dhcp3; now they are under /etc/dhcp:

Image /etc/dhcp/dhcpd.conf

This is the configuration file for the DHCP server. By default it is a heavily commented file that should provide plenty of examples for you to work from.

Image /var/lib/dhcp/dhcpd.leases

This file contains the current list of DHCP leases your server has handed out. If you are wondering what MAC address got a particular IP, or when a particular lease will expire, look in this file.

Image /var/log/syslog

DHCP uses the standard syslog file for all of its logs. Here you will be able to find any requests from the network for a DHCP request along with the DHCP server’s reply.

Configure DHCP

Ubuntu provides a heavily commented DHCP configuration file that explains all of the major options and gives a number of different configuration examples. For basic DHCP services you generally want to set up one or possibly two scenarios: dynamic DHCP and static DHCP. In a dynamic DHCP configuration new hosts get assigned an IP out of a possible range of IPs. There’s no guarantee a host will get assigned the same IP every time. With static DHCP you can bind a particular IP address to a host’s MAC address and ensure that every time it shows up on the network it will get the same IP. Dynamic DHCP is good for a simple, easy-to-maintain DHCP server, and static DHCP gives you a lot of the benefits of static IPs without nearly as many headaches. Plus with static IPs, if you do want to change the IP address of a host, you can do so in the dhcpd.conf file and reload DHCP instead of having to track down and change the host.

For both of my examples I set up DHCP for a local office network, example.net, on 10.1.1.0, subnet 255.255.255.0. The gateway is at 10.1.1.1 and the name servers are at 10.1.1.2 and 10.1.1.3.

Dynamic DHCP Configuration

To set up dynamic DHCP, open the /etc/dhcp/dhcpd.conf file and move to the bottom of the file to pass all of the example options. All you need to add is a single subnet declaration that provides all of the information about your subnet that DHCP needs to hand out, along with the range of IP addresses DHCP can use. In my example I hand out 10.1.1.50 through 10.1.1.99, so I add the following settings to the bottom of the file:

subnet 10.1.1.0 netmask 255.255.255.0 {
    range 10.1.1.50 10.1.1.99;
    option routers 10.1.1.1;
    option domain-name-servers 10.1.1.2, 10.1.1.3;
}

Now to start DHCP and enable my settings, I would run sudo start isc-dhcp-server. If I didn’t make any syntax errors, the DHCP server will start up. If there is an error in the file, it should output to the screen along with its location. A common error is a missing semicolon at the end of a particular line.

Static DHCP

You can use static DHCP assignments along with a dynamic DHCP subnet declaration if you want. If a server matches a static assignment, it will get that address; otherwise it will default with an address in the dynamic range. Each host that gets a static assignment needs its own host declaration. For instance, here is a host declaration for a host with a MAC address of 00:0c:c0:ff:ee:00 that will be assigned 10.1.1.10:

host examplehost {
    hardware ethernet 00:0c:c0:ff:ee:00;
    option host-name "examplehost";
    fixed-address 10.1.1.10;
}

You can add as many host declarations as you want; just keep in mind that each one needs to have a unique MAC address and a unique IP address in this file. Once you have added all of your host declarations, save your changes and restart the dhcp3-server init script.


Note: How to Find Your MAC Address

If you aren’t sure how to tell what MAC address a particular host has, log in to the host and then run sudo ifconfig:

$ sudo ifconfig
eth0     Link encap:Ethernet  HWaddr 00:0c:c0:ff:ee:00
         inet addr:10.1.1.10  Bcast:10.1.1.255  Mask:255.255.255.0
         UP BROADCAST MULTICAST  MTU:1500  Metric:1
         RX packets:0 errors:0 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000
         RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
         Interrupt:10

lo       Link encap:Local Loopback
         inet addr:127.0.0.1  Mask:255.0.0.0
         inet6 addr: ::1/128 Scope:Host
         UP LOOPBACK RUNNING  MTU:16436  Metric:1
         RX packets:2741 errors:0 dropped:0 overruns:0 frame:0
         TX packets:2741 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0
         RX bytes:148411 (148.4 KB)  TX bytes:148411 (148.4 KB)

Look for the HWaddr section in the output. That section will show that network device’s MAC address, in my case 00:0c:c0:ff:ee:00.


Database Server

Flat files and spreadsheets can work for data storage for some time, but at some point you will recognize the need for a real database. Most complex Web sites these days (including the WordPress example in this chapter) expect a database at the back end to store account information, blog posts, forum settings, and any other information about the site. There are a number of different databases available for Ubuntu, including Oracle, but here I discuss how to set up the two most common databases: MySQL and Postgres.

MySQL

MySQL has long been a favorite database server, particularly as a back-end database for Web sites because of its simple setup and fast performance. It’s so popular for this purpose that an acronym, LAMP (Linux Apache MySQL Perl/PHP/Python), was created to describe it.

Install MySQL

There are a few different ways to install the MySQL server. If you choose LAMP Server during the Ubuntu install or afterward with tasksel, MySQL will get installed along with Apache and PHP. Alternatively, you can install the MySQL server package directly:

$ sudo apt-get install mysql-server

During the package installation you will be prompted to set a password for the root MySQL account. You can choose to leave it blank; however, I recommend that you take this opportunity to set the password. It’s certainly simpler to set it here than to look up the MySQL commands to set it later. Once the package installs, the MySQL daemon will start and it will be ready for you to use.


Note: How to Configure Cron for Passworded MySQL

If you do change the password of the root MySQL user (and you should), you will need to set up a small configuration file for cron to use so that it can run its MySQL /etc/ cron.daily/ script successfully. To do this, create a /root/.my.cnf file containing the following information:

[mysqladmin]
user       = root
password   = yourpassword

Since this file contains a password in plain text, you will want to secure the permissions to make sure that no one other than root can read it:

$ sudo chown root:root /root/.my.cnf
$ sudo chmod 0600 /root/.my.cnf


Ubuntu MySQL Conventions

This section describes the major directories and file locations for MySQL along with their use:

Image /etc/mysql/

This directory contains the main configuration files for MySQL.

Image /etc/mysql/my.cnf

This is the core MySQL configuration file. Individual users can create their own custom configurations as well and store them in ~/.my.cnf (as we did for the root user).

Image /etc/mysql/debian-start and /etc/mysql/debian.cnf

These files are a script and configuration file, respectively, that manage processes that Ubuntu runs whenever the MySQL init script is started or restarted. This script checks for crashed tables and corrupt data, and overall checks to make sure that the database came up cleanly. You can think of this script almost like the file system check the system performs at start-up.

Image /etc/mysql/conf.d/

This directory is included by the main my.cnf and allows a better way to organize configuration files for particular databases or sites. Any configuration file created here will be included along with the main settings for MySQL when it starts.

Image /etc/init.d/mysql

The main MySQL init script is set to automatically start at boot time and stop when the system is rebooted or halted. Like many service init scripts, it supports extra options such as reload and force-reload to reload configuration files, as well as status to report the current status of the service. As you will see, Ubuntu also includes a better command-line tool for managing MySQL.

Image /var/log/syslog

Ubuntu sets MySQL to log to the standard system log file, instead of /var/log/mysql.log or files under /var/log/mysql/. So to view only MySQL-related log entries from your syslog, you can use a simple grep command:

$ sudo grep mysqld /var/log/syslog

Image /var/lib/mysql/

Under this directory you will find all of the database files used by the active database.

mysqladmin

Ubuntu includes the mysqladmin tool to help with MySQL administration. You can think of it as being like the apache2ctl program in that it accepts certain commands on the command line and then interacts with the mysqld process for you. For instance, to get the current status of your MySQL process, you can run

$ sudo mysqladmin -p status

The program will return information such as the current uptime, how many threads are active, how many slow queries are running, and the average queries it processes per second. Note that I used the -p argument in this command, which will tell mysqladmin to prompt me for the password on the command line. If you set a password for the root user, you will need to use -p with your commands, or if you plan to run a batch of commands and don’t want to enter the password every time, you can add the password to the -p option. So, for instance, if my MySQL password was insecure, I would type the following:

$ sudo mysqladmin -pinsecure status

The mysqladmin manual page (type man mysqladmin on a console) lists the full set of commands, but a few of the common ones are highlighted here:

Image create and drop

The create and drop commands take a database name as an argument and respectively create or remove a database from your MySQL instance.

Image flush-*

There are a number of commands that flush caches or other settings within MySQL. The flush-hosts, flush-threads, and flush-logs commands flush the host cache, thread cache, and all logs, respectively. The flush-privileges, flush-status, and flush-tables commands reload the grant tables, clear status variables, and flush all tables, respectively.

Image password

If you never set the root password to begin with, or you want to change it, use this command with the new password as the next argument. If the password contains any special characters or spaces, be sure to put them in double quotes.

Image status, extended-status, processlist

All of these commands provide you with information about the current MySQL instance. I’ve already discussed the status command. The extended-status command provides a more complete set of status information, and the processlist command lists all of the active server threads along with their IDs. You can use that ID as a reference if you need to kill a particular process.

Image kill

The mysqladmin processlist command lists all of the processes along with their IDs, and the kill command kills all of the process IDs you pass as arguments. If you specify multiple processes, separate them with commas.

MySQL Web Administration

While hard-core database administrators might scoff at using a Web interface to administer MySQL, it is a popular way to create and modify databases, particularly among Web designers. The phpMyAdmin program is a popular Web interface to MySQL, and it is easy to set up under Ubuntu.

Install phpMyAdmin

To install phpMyAdmin, use your package manager to install the phpmyadmin package:

$ sudo apt-get install phpmyadmin

This will grab not only the phpmyadmin package but also its dependencies, including apache2, if you don’t already have a Web server installed. During the package installation you will be presented with some questions to configure phpMyAdmin. The first question is which Web server to use. Unless you specifically set up another Web server for this task, select apache2 here.

Once the package installation completes, phpMyAdmin should be ready to use. Just open a Web browser and point to the IP address or hostname of the phpMyAdmin server and append /phpmyadmin to it. So if my server was at 192.168.1.7, I would browse to http://192.168.1.7/phpmyadmin. The first screen you will see is a login screen, as shown in Figure 5-3. It’s important to remember that phpMyAdmin does not maintain any user accounts on its own—it simply passes your login and password directly to MySQL—so type in root and your MySQL password (or if you have set up other users on MySQL, type that information in here). Once you log in, you will see the main configuration screen as shown in Figure 5-4, and from there you can tweak your MySQL settings, create and modify databases and tables, and access the phpMyAdmin documentation itself.

Image

Figure 5-3 phpMyAdmin login screen

Image

Figure 5-4 Main phpMyAdmin configuration screen

PostgreSQL

PostgreSQL and MySQL are the yin and yang of the open source database world. Whereas MySQL focused on speed and ease of use early on and then started to add more advanced database features, PostgreSQL focused on advanced database features first and then worked on optimization and ease of use. Both databases have their following, and all of the major open source database-backed Web software supports both databases. PostgreSQL moves far beyond Web site databases, though, with an advanced feature set including full ACID compliance, foreign keys, joins, views, triggers, and stored procedures.

Install PostgreSQL

Even though MySQL has the reputation of ease of use, PostgreSQL under Ubuntu is also simple to install and use. To install PostgreSQL, you can either select PostgreSQL Server as you install Ubuntu or afterward with tasksel, or you can use a package manager to install the postgresql package:

$ sudo apt-get install postgresql

Once the postgresql package has been installed, the database service will start in the background and you can then set up your superuser account and create a database. The initial administration will be performed by the postgres user, so first use sudo to become that user:

$ sudo -u postgres -s

Now from this shell you can create a new user account. You can choose to maintain the postgres user as the main superuser and then control who can become that user with sudo, or alternatively you can set up a new database user with superuser privileges. If I wanted to create a new superuser on my PostgreSQL database with the username kyle, I just need to pass the right flags to the createuser program:

$ createuser -P -s -e kyle
Enter password for new role:
Enter it again:
CREATE ROLE kyle PASSWORD 'md56966c432c869202883876a8b4f925ccc'
SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;

Alternatively, if I just wanted to create a regular unprivileged user:

$ createuser -P -DRS kyle
Enter password for new role:
Enter it again:

If you make a mistake and want to try again, or if you want to delete a user in general, just use the dropuser command with the username as an argument. Now that I have created a user, I can set up a database owned by that user. The createdb does all of the heavy lifting; I just need to specify the owner and the name of the database, in this case kyledatabase. So while I’m still the postgres user, I type the following:

$ createdb -O kyle kyledatabase

Now I can type exit to exit out of the postgres shell and back to my normal user. To access the database I can use the psql command as my regular user:

$ psql --password kyledatabase

Now if my PostgreSQL username is different from the name of my shell account, this will error out as by default it tries the username of the local account. In that case I can add the PostgreSQL username at the end of the command:

$ psql --password kyledatabase kyle

Ubuntu PostgreSQL Conventions

This section describes the major directories and file locations for PostgreSQL along with their use:

Image /etc/postgresql/

Here you will find the main configuration files for all PostgreSQL instances on the system. Because the configuration files between different PostgreSQL versions can be incompatible, Ubuntu gives each PostgreSQL version its own subdirectory here. That way you can easily maintain multiple PostgreSQL versions on the same machine. For instance, the default postgresql package under Precise will install PostgreSQL version 9.1, so all of its configuration will fall under /etc/postgresql/9.1/.

Image /etc/postgresql/9.1/main/postgresql.conf

The /etc/postgresql/9.1/main/ directory contains the main configuration files for PostgreSQL 9.1, with postgresql.conf being the primary configuration file. This file is heavily commented, so you can use the file as a reference when you change options.

Image /etc/postgresql/9.1/main/pg_hba.conf

This is the configuration file that stores all host authentication information. Here you can control which hosts on the network can access the PostgreSQL database.

Image /etc/postgresql/9.1/main/pg_ident.conf

The pg_ident.conf file allows you to map a local username on the server to a different PostgreSQL username. So if your local username and PostgreSQL username don’t match, you can add a mapping here and avoid having to add the PostgreSQL username to the command line each time you run psql.

Image /etc/init.d/postgresql

This is the init script for PostgreSQL 9.1.

Image /var/log/postgresql/

Unlike MySQL, which logs to syslog, PostgreSQL separates all of its logging under /var/log/postgresql. From there each log is labeled according to its version, so the default PostgreSQL 9.1 database under Precise logs to /var/log/postgresql/postgresql-9.1-main.log.

Web-Based PostgreSQL Administration

If you think hard-core MySQL administrators balk at Web-based administration, you should see how hard-core PostgreSQL administrators react. Even so, if you just want to create a Web site that is backed on a solid PostgreSQL database, you might appreciate the simplicity of managing the database from the Web. As with MySQL, there is a PHP-based administration tool called phpPgAdmin. To install phpPgAdmin, you simply need to install the phppgadmin package:

$ sudo apt-get install phppgadmin

The package will download all of its dependencies, including a Web server if one is not already installed. Once the package installs, create a symlink to its Apache configuration file under /etc/apache2/sites-available and then use a2ensite to enable the site:

$ sudo ln -s /etc/phppgadmin/apache.conf /etc/apache2/
  sites-available/phppgadmin
$ sudo a2ensite phppgadmin
$ sudo apache2ctl graceful

By default phpPgAdmin is configured to allow only localhost to access the site, so to allow access from your local network, open /etc/phppgadmin/ apache.conf and locate the line that says

allow from 127.0.0.0/255.0.0.0

To allow the 192.168.1.0 network to access the tool as well, add

allow from 192.168.1.0/255.255.255.0

below the other allow from line and then run sudo apache2ctl graceful to reload your changes. Now you can open a Web browser on your network and browse to the /phppgadmin directory on the phpPgAdmin host. So if its IP address was 192.168.1.7, you would browse to http://192.168.1.7/phppgadmin/ and see the default Web page shown in Figure 5-5.

Image

Figure 5-5 phpPgAdmin default page

The main page lists all of the available PostgreSQL servers in the left sidebar. By default you will have just one configured, so click it and then use your PostgreSQL credentials to log in and manage the server. As Figure 5-6 shows, the interface is different from phpMyAdmin’s, but as with phpMyAdmin you can modify databases, change tables, and perform all of the other major database administration you might want.

Image

Figure 5-6 phpPgAdmin database administration

File Server

I suppose you could think of a Web server as a file server in a way—it does share files—but generally speaking, when people think of file servers they think of a machine on the local network with a lot of storage and the ability for multiple hosts on the network to access and modify files on that server. There are two main file servers for Ubuntu that most people favor: Samba and NFS. While both can work across multiple platforms, most administrators tend to favor Samba when their clients are mostly Windows, and NFS when their clients are mostly Linux. Both are relatively simple to set up on Ubuntu.

Samba

Samba is a program that implements Windows file-sharing protocols, SMB and CIFS. As such it’s ideal as a platform for file sharing under Windows, since all of the clients can access the server without additional software. Over time Samba has grown to support advanced sections of Windows file sharing to the point that it can operate much like any other Windows file server or Primary Domain Controller.

Install Samba

To install Samba, you can either select the Samba Server option during the Ubuntu install or after the install with the tasksel program, or you can install the samba, samba-doc, smbfs, and winbind packages separately with the package manager:

$ sudo apt-get install samba samba-doc smbfs winbind

The Samba service will start automatically; of course, by default nothing too interesting will be shared, so you will need to tweak Samba’s configuration files before any directories are shared.

Ubuntu Samba Conventions

This section describes the major directories and file locations for Samba along with their use:

Image /etc/samba/

This directory contains all of the main configuration files used by Samba, including local password files.

Image /etc/samba/smb.conf

The smb.conf file is the core configuration file for Samba and is used to define file shares and global settings for Samba itself. The default smb.conf file is heavily commented and sets up sane defaults for the file server such as a default workgroup of Workgroup. The file also contains a number of different examples of how to set up shares, including a useful example configuration that shares out all of the users’ home directories, but by default all of these sample shares are commented out.

Image /etc/init.d/smbd, /etc/init/smbd.conf

Samba’s init script has been converted to an Upstart script, although there is still an old init script available as a placeholder. This means that you will use the standard Upstart programs like start, stop, and status to manage the service. Samba automatically starts at system boot by default.

Image /etc/init.d/nmbd, /etc/init/nmbd.conf

Like the smbd init script, the nmbd init script is also managed by Upstart now.

Image /usr/bin/smbpasswd

This tool is used to create user accounts for Samba. If you want to set up Samba shares that require authentication, you use this tool to create a Samba user database. Samba usernames that you add need to already exist on the system as well. For example, to add an ubuntu user to Samba, I would type

$ sudo smbpasswd -a ubuntu

I can also use this command when I want to change the password for a particular user. To delete a user from Samba, replace the -a option with -x. You can also temporarily disable Samba users without deleting their accounts. To do this, use the -d and -e options to disable and enable the user, respectively.

Image /usr/share/doc/samba-doc/

If you installed the samba-doc program, you will find Samba documentation and example configuration files under this directory.

Image /var/lib/samba

This directory contains all of the different databases used by Samba, including the user and password database used by smbpasswd.

Image /var/log/samba/

Samba logs in to its own directory and creates separate log files for the smbd and nmbd processes (log.nmbd and log.smbd respectively) as well as a separate log for each host that accesses Samba. This organization can make it easier to narrow down to the logging information you need.

Sample Samba Configuration

A good way to set up a new Samba share is to read the comments in the /etc/samba/smb.conf file. There are many different examples that show you how to share the user home directories or the CD-ROM drive, for instance. In this example I will show how to share a directory located at /mnt/share so that everyone on the network can access and write to it as a general storage location. Open /etc/samba/ smb.conf in your preferred text editor and move to the bottom of the file. Then add the following:

[general]
    path = /mnt/share
    comment = General Storage
    writeable = Yes
    browseable = Yes
    guest ok = Yes
    force user = ubuntu

In this example I have set up the /mnt/share directory so that anyone on the network can write to it (writeable = Yes, guest ok = Yes) and use the force user = ubuntu option so that when a user creates a file on the share, it will be owned by the local user named ubuntu. Of course you would want to change this user from ubuntu to a user that exists on your system. Now I can create the shared directory and make sure that its permissions are set so that the local ubuntu user can write to it:

$ sudo mkdir /mnt/share
$ sudo chown ubuntu:ubuntu /mnt/share

One nice feature of Samba is that I can add or tweak a share like the preceding one without having to restart Samba. This is handy because when you restart Samba, any user accessing a file on the share will temporarily be disconnected from the file. Certain programs react very poorly to having their files pulled out from under them, even temporarily, and I’ve seen some simply crash when this happens.

Now that Samba is configured, go to another host on the network and attempt to connect to your Samba server. On an Ubuntu desktop you would click Places > Connect to Server..., then select “Windows share” from the “Service type” drop-down menu. Finally you would enter the IP address or hostname for your Samba server and then enter general for the name of the share (or otherwise whatever name you put between the brackets in your smb.conf). Click Connect and Ubuntu will mount and display the mounted share on your desktop.

NFS

NFS is a file-sharing service that originated on UNIX instead of Windows. These days both Linux and Windows can mount NFS shares, but you still tend to see NFS used with a network of Linux or UNIX clients. As you will see, there isn’t too much involved if you want to share a directory over NFS.

Install NFS

To install NFS, select the nfs-kernel-server in your package manager. This will download and install the service along with any extra dependencies you need.

$ sudo apt-get install nfs-kernel-server

After the package installs, NFS is ready to be configured. By default no NFS exports will be configured, so nothing will be shared until you explicitly configure it.

Ubuntu NFS Conventions

This section describes the major directories and file locations for NFS along with their use:

Image /etc/exports

This is the core configuration file for NFS and contains a list of all file systems that NFS will export to users.

Image /etc/init.d/nfs-kernel-server

This init script controls the NFS server and accepts the standard list of init script options, including reload, so that you can reload the configuration without restarting the service.

Image /var/log/syslog

NFS logs to the standard syslog file as the NFSD process. This is the place to look if a remote host can’t access a share and you want to track down exactly what is failing. To view only NFS logs from this file, run sudo grep NFSD /var/log/syslog.

Sample NFS Configuration

It is relatively simple to add NFS shares, and all of your work will be done in the /etc/exports file. The syntax of the file is covered in detail in the exports man page, which you can access by typing man 5 exports. Generally, the file will contain one export per line, and each line has two columns separated by one or more spaces. The first column is the path to the directory to share, and the second column is the host or network allowed to access the share along with a set of options within a pair of parentheses.

I create a sample share much like the example I gave in the Samba section. I export the /mnt/share directory owned by the ubuntu user to everyone on the 192.168.1.x network. To do this, I just need to add the following line to /etc/exports:

/mnt/share 192.168.1.0/255.255.255.0(rw)

Now I set up the /mnt/share directory if it isn’t already there:

$ sudo mkdir /mnt/share
$ sudo chown ubuntu:ubuntu /mnt/share

Finally, I can reload NFS to enable this share:

$ sudo service nfs-kernel-server reload

Once NFS has reloaded, I can go to any host on the 192.168.1.0 network and mount the share. If the NFS server were at 192.168.1.7 and I wanted to mount it at /mnt/local, I would type

$ sudo mount -t nfs 192.168.1.7:/mnt/share /mnt/local

If your Ubuntu host gets an error about wrong file system type, you likely haven’t installed NFS client support on your system. Just run

$ sudo apt-get install nfs-common

and try the mount command again.

NFS User Permissions

One interesting and controversial feature of NFS is how it handles user permissions. When you mount an NFS share, the file ownership will be based on the user IDs of the users on the NFS server. For users on a remote system to be able to read and write to the share, their user IDs need to match up with the NFS server. If you use LDAP or some other system to keep user IDs consistent across servers, this shouldn’t present much of a problem, but if, for instance, the ubuntu user on my NFS server had a user ID of 1000 but the ubuntu user on my client had a user ID of 1001, the client wouldn’t be able to write to the mount point.

Another matter of interest with NFS permissions is how it handles root. On Ubuntu by default the root account will be squashed, because NFS blocks any attempts by a remote root user to access shares with its root privileges. Otherwise any host on the network with an Ubuntu live CD could boot it, mount the NFS share, and read and write to any files on that share, regardless of the permissions. With this security issue in mind, you still might want to disable root squashing. To do so, add the no_root_squash option to your list of export options in /etc/exports. Each option is separated by commas, so if I wanted to disable root squashing on the share I created earlier, the file would look like the following:

/mnt/share 192.168.1.0/255.255.255.0(rw,no_root_squash)

Edubuntu and LTSP

The community-driven Edubuntu project aims to create an add-on for Ubuntu specially tailored for use in primary and secondary education. Edubuntu exists as a platform for tools for teachers and administrators. But the real thrust, of course, and the real purpose, is to put free and open source software into the hands of children. In doing so, Edubuntu provides children with a flexible and powerful technological environment for learning and experimenting. Based on free software, it offers educational technologies that are hackable and that can ultimately be used by students and teachers on their own terms. Distributed freely, its gratis nature serves an important need for schools where technology programs are always understaffed and underfunded. Fluent in Ubuntu and in free software, the children who, right now, are growing up using Edubuntu are offering the Ubuntu community a glimpse of where it might go and the generation of Ubunteros who may take us there.

While the Ubuntu, Kubuntu, and Xubuntu desktops highlight the products of the GNOME, KDE, and Xfce communities respectively, the Edubuntu project provides the best of everything in Ubuntu—properly tailored for use in schools and as easy to use as possible. One thing that made Edubuntu popular was its amazing ability to integrate thin clients, allowing the use of one powerful machine (the server) to provide many very low-powered, often diskless machines (the clients) with their entire OS. (See the next section for more information.) This model, while uninteresting for most workstation and laptop use by home or business users, is a major feature in classroom settings where it can mitigate configuration and maintenance headaches and substantially reduce the cost of classroom deployments.

What Is LTSP?

LTSP stands for Linux Terminal Server Project. It provides the same functionality to current client/server models that was present in the mainframe/dumb terminal setups prevalent many years ago.

The LTSP model centers on one powerful machine that acts as a server and several often much lower-powered machines that act as clients. The machines are all connected on a local area network.

This network allows all data required for booting the client’s computer, which is normally held on the client’s hard drive, to be served to the client over the network. If all the data required for booting the computer is provided over the network, the client machine requires no storage media at all, which leads to the term diskless clients.


Tip

Clients require a network card, which can boot either via PXE or via Etherboot to allow initial booting for local media before piggyback booting from the network. More information can be found at http://rom-o-matic.net, where you can create bootable images for your network hardware. Etherboot is essentially a convenient way to emulate the PXE system on older hardware. Most newer motherboards and network cards come with PXE software on the chip.


Technical Details of the LTSP Boot Process

A client machine is switched on. After the hardware is initialized, the network card looks for an IP address via the DHCP protocol. The LTSP server in most cases acts as the DHCP server to the local network and sends the client machine its IP address. Figure 5-7 shows a diagram of the LTSP booting process.

Image

Figure 5-7 LTSP booting process

Once the network card has bound the IP address to itself, it makes a connection to the LTSP server and asks for the PXE configuration file. The LTSP server sends this file back to the client machine, which then makes a request for the kernel image. This is the base of the OS, which provides the client with all the hardware drivers required to communicate with the server.

Next, an NFS connection is set up with the server. This is almost like a standard network share. The NFS share holds a very cut-down installation of Ubuntu, which consists almost entirely of an X server and an SSH-based login manager to connect to the server. Once the client machine has finished booting this small version of Ubuntu, the login screen is displayed to the user.

When a user logs in, an SSH tunnel is opened to the server, and an X session is initiated through this tunnel. All programs are run on the server, and only the graphical interface is piped back to the client machine. This allows the user to interact with the session and use a computer as normal.

The whole process is totally transparent to the user, but it is important to have a basic understanding of the underlying technologies present in LTSP to assist in the troubleshooting process and to be able to evaluate LTSP for a given task.

The Benefits of LTSP

Booting computers in this way does have some distinct advantages over the current preferred model of many powerful desktops, particularly where only a low budget is available. Here are the benefits:

Image Singular point of administration: Working with this model means that only one computer needs to have new software installed on it. By using the Add/Remove tools, as demonstrated later in this chapter, you can make applications automatically available to all clients because they are essentially all using the same machine.

Image Low-cost hardware: Thin client machines are not required to be incredibly powerful because all processing is done by the server. This allows people to use much older hardware for their client machines, often reusing machines that were taken out of service for being sluggish several years ago.

Image Diskless clients: Anyone who has spent time administrating a network knows that often a computer used regularly suffers from corrupt files on the hard disk and needs reinstalling. If a client has no disk, there is no chance of a user corrupting data on the client’s hard drive.

Image Easy replacement: If one of your thin client machines breaks down, you still have all your data stored on the server. Just replace the client hardware and carry on working. It really is as easy as changing a light bulb.


Tip

Thin clients can run on incredibly low-specification machines. People are running thin clients on recycled computers that are as low-powered as 133MHz Pentiums with 64MB of RAM. While performance becomes an issue on hardware this slow, simple tweaks to avoid encryption over SSH can mitigate these. Generally, a machine running at least a 400MHz processor with 128MB of RAM will make an excellent thin client.


Other Uses

The LTSP system has its uses in many other applications too. Imagine you are running an Internet cafe, where many people use the computers in exactly the same way. Each workstation would need the same set of applications installed. The tasks they are performing are not hugely CPU intensive, so a thin client system is perfectly suited to this type of application. You will also find LTSP solutions very commonly used in information systems (e.g., in airports) and in point-of-sale systems.

LTSP Availability in Ubuntu

The ability to install and configure the LTSP system automatically is available to the user with the Ubuntu alternate CD. Since Edubuntu is no longer available as a live or alternate CD, the LTSP server installation has been moved to the Ubuntu alternate CD. If installation of LTSP is required to an already installed Ubuntu, Kubuntu, or Xubuntu desktop or Ubuntu server, you should follow the instructions provided in the next section.

Installing an LTSP Server

Starting with Ubuntu 9.04, the LTSP installation process requires one minor step before proceeding. The first thing you need to do is acquire the Ubuntu alternate CD. LTSP server installation is no longer provided via an Edubuntu CD because the status of Edubuntu has changed from a distribution to an add-on. If you would like to add LTSP to an Ubuntu server you have already installed, skip ahead to the “Installing the LTSP Environment in Ubuntu or on a Desktop Installation” section in this chapter.

LTSP Server Configurations

The LTSP server install allows a great deal of flexibility and is designed to allow it to fit into any current network configuration. Essentially these fall into two categories: those that use the LTSP server as a primary gateway for all their LTSP clients and those that do not. Let’s take a few minutes to discuss the relative merits of each system.

Using the recommended configuration requires the LTSP server machine to have two network interface cards (NICs). One of these cards is connected to the rest of the network, that is, to the Internet or to other servers on the internal network. The other card is usually connected to a private subnet of the network where only Edubuntu LTSP clients reside. Figure 5-8 shows this two-NIC setup. No network data is routed from the second network card to the first, so client machines must be authenticated on the LTSP server before having access to the Internet or the rest of the network. This makes for a secure network setup.

Image

Figure 5-8 Two-NIC setup

The benefit to this setup is that client computers cannot connect to the network unless the LTSP server permits them to. This also reduces network traffic on the rest of the network because while the LTSP clients are booting from the LTSP server, data is being transferred only on the private subnet and not on the rest of the network. Also, the clients receive their network addresses from the LTSP server, which frees up addresses on the rest of the network.

Using LTSP as simply another server on a network allows for a more flexible atmosphere. For a start, you require only one network interface card in the server to run using this configuration. The LTSP clients are connected to the normal network and could, assuming they had the capabilities to boot, access the network without the help of the LTSP server. Figure 5-9 shows this one-NIC setup.

Image

Figure 5-9 One-NIC setup

The benefits of this setup are that thin clients can be used with more than one OS. One establishment, for example, runs dual-booting Microsoft Windows and Edubuntu clients. This setup also allows users to have their LTSP thin clients receiving their DHCP network addresses from a single network server.

Essentially the choice of network design layout will impact the number of network cards installed in your server. It is primarily this that affects the difference between the standard Ubuntu install and the LTSP install.

The Installation Procedure

The installation procedure from the Ubuntu alternate CD looks very different from that of the desktop CD, but the questions asked are largely the same. The alternate CD is all text based, which can be a little daunting at first, but you will find installing Ubuntu in this way quicker because it doesn’t require the entire desktop session to be loaded.


Tip

Remember that the server CD sets up LTSP for you. If you are planning to run an LTSP server, the easiest installation method is to use the Ubuntu alternate CD.


After the CD has booted, press F4 and select “Install an LTSP server,” and then select the “Install to the Hard Disk” option. Confirm by pressing Enter to begin the installation. Notice also the workstation and command-line options at this point.

The first question you are asked simply sets up the language used for the install procedure as well as the language for the final system. You are then asked to choose your location.

Now you must choose your keyboard layout. The text-based installer has an auto-detection routine that asks you to press a series of keys on the keyboard. From these keys, the installer can work out which keyboard layout will best suit you. If there are any keyboard variations, these are now presented for you to choose from.

The installer now loads various components. If you have more than one NIC in your computer, you are asked to choose the primary card for the installation (see Figure 5-10). By this, the installer wishes to know which network card is connected to the outside network or the Internet.

Image

Figure 5-10 Selecting the primary network interface

If your network has DHCP enabled, this card will be set up with an IP address from the network. You are then prompted to choose a hostname for the LTSP server. If your network doesn’t have DHCP enabled, you must set up the IP address manually.

The next step is to set up the hard disk for installation. By far the easiest method here is to select the default option of Guided Partitioning. If you require more in-depth partitioning or already have data on the hard drive that you do not want to lose, you must plan how you are going to proceed. If you are installing onto a computer that has partitions Ubuntu can resize, it will offer you that option. This option allows you to have two OSes installed on one computer and to switch between them at bootup. Whichever method you select, you are asked to confirm your partitioning choices.


Warning

While the resizing utilities in Ubuntu are excellent, you should always back up your data before performing an operation such as this.


After this, you must choose whether or not your clock is set to Coordinated Universal Time (UTC). Your system clock should be set to UTC. Your OS is then responsible for converting the system time into local time. Unless you have another OS that expects the system time to be the local time, you should answer yes here.

Now it’s time to set up the first user on the system. Remember that this user will have full administrative rights. First, enter the user’s full name, then the desired username, followed by the password twice. After this, the base system is installed.

After plowing through several steps, you are presented with a question about screen resolutions. For the type of system you are installing, a very high screen resolution could result in a slow connection between the server and the client. The default options are fine.

When this is completed, the installer begins building the LTSP client root filesystem as shown in Figure 5-11. This is the very small version of Ubuntu mentioned earlier in this chapter. Essentially it consists of just a kernel and an X server.

Image

Figure 5-11 Building the LTSP filesystem


Warning

This step appears to take a long time, and the progress bar isn’t updated often. Be patient, have a snack—it will finish eventually.


Once the installation is complete, a prompt asks you to remove the CD and press Enter to reboot the system into your new Edubuntu server.

Initial LTSP Server Setup

The DHCP server installed on your Ubuntu machine should start up automatically, so all that is left to do is to make your thin clients bootable from the network. If you are using the single–network card setup described earlier and your network already has a DHCP server running, do not start the Ubuntu DHCP server, because doing so will likely cause both DHCP services to be unavailable.


Tip

If you are still running the Dapper 6.06 LTS version of Edubuntu, there is a little bit more work to do. The latest versions of Ubuntu have an automatic DHCP configuration generator. This means that they do not require manual configuration in usual LTSP environments. The 6.06 LTS release needs manual configuration of the DHCP server; please visit https://www.edubuntu.org/GettingStarted for further instructions.


Initial LTSP Client Setup

Modifying a client computer to boot from the network is usually done by altering a setting in the machine’s BIOS. It’s a good idea to look at the manual for the computer’s motherboard to find out how to alter these settings. For most machines it is simply a case of entering the BIOS by pressing the Delete key at bootup and changing the boot device priority.

Once you’ve set up your client machines to boot from the network card, you should see a screen similar to the one Figure 5-12 shows on each of the clients. This means that the client machine has been issued with a DHCP address and that the PXELinux file has been loaded from the network.

Image

Figure 5-12 DHCP boot

If your client boots up to the graphical login and the screen looks similar to the one shown in Figure 5-13, congratulations—you have successfully set up your LTSP thin client system.

Image

Figure 5-13 LDM login screen

Installing the LTSP Environment in Ubuntu or on a Desktop Installation

Perhaps you already have an Ubuntu machine and wish to make it available in an LTSP setup. To do this is a simple procedure and requires very little configuration. To begin, you must decide whether you require a DHCP server. If so, install the ltsp-server-standalone package. If you already have a DHCP server and are going to configure it to point to the LTSP server, by modifying the filename, next-server, and root-path options, you should install the ltsp-server package. Along with this, you will need the openssh-server package.

The easiest way to do this is to log in to your server and type the following commands to install the LTSP server and the SSH server. In our example, a DHCP server was not required.

sudo apt-get install ltsp-server openssh-server


Tip

If you require a DHCP server, modify the preceding line from ltsp-server to ltsp-server-standalone. You will also need to configure a second network device to an IP address of 192.168.0.1 before running the procedures described in this subsection.


All that is left to do now is to install the client chroot by running the following command:

sudo ltsp-build-client

After this, you should be able to boot your first thin client.

Special LTSP Cases

The preceding steps work to get an initial LTSP Install working, but some special cases require a bit of extra configuration. We go over some of these special cases shortly.

Setting Up LTSP to Coexist with an Existing DHCP Server

Sometimes you might not want your machines to be on a totally separate subnetwork. However, the problem then becomes that the current DHCP server will not be set up to serve the correct options to enable the clients to boot from the network. Modifying a Linux-based DHCP server is well documented; however, some establishments will require the modification of a Microsoft Windows DHCP server to allow network clients to boot from the network.

The following setup assumes that there are currently no thin client systems running on the Windows network. Opening up the Windows DHCP administration tool will allow you to create reservations for your machines. A reservation is an IP address tied to a specific MAC address. In this way, each time a machine requests an IP address from the DHCP server, it is always given the same IP address. This has its benefits because you can then set advanced options for the client as well.

For each client, you must create a reservation and then add the following options to each one (Figure 5-14).

Image 017 Root Path: /opt/ltsp/i386

Image 066 Boot Server Host Name: <server ip>

Image 067 Bootfile Name: /ltsp/i386/pxelinux.0

Image

Figure 5-14 Windows DHCP Reservations

It is recommended that you restart the DHCP server. After this, the clients should be able to correctly pick up their IP address from the server and then boot from the LTSP server via NFS.


Tip

You can also set these options as global parameters to be rolled out over the entire network. However, it is often advisable, at least in the beginning, to keep track of which machines are booting from the LTSP server.


Dual-Booting with Another Operating System on the Hard Disk

Perhaps you have a suite of computers that are already happily running another OS, and you would prefer to keep both systems running for a while. Hopefully, after using Edubuntu for any length of time, you will eventually make the switch permanent. In these situations, it is easy to set up the server to allow the client to boot from either the network or the first hard disk in the computer.

The bulk of the editing takes place in the pxelinux.cfg/default configuration file in the directory /var/lib/tftpboot/ltsp/<arch>/. The format of this file is very similar to the old LILO configuration syntax (for those of you familiar with that bootloader). The following sample configuration will present a message to the client, which is explained later. The user can then choose to either allow the system to boot its default configuration, which in this example would be the local hard disk, or to type in the word linux and press Enter, which would load the LTSP thin client.

DEFAULT localboot
TIMEOUT 50
PROMPT 1
DISPLAY display.msg

LABEL linux
  KERNEL vmlinuz
  APPEND ro initrd=initrd.img quiet splash

LABEL localboot
  LOCALBOOT 0

Let’s take a look at the configuration file and break it down so that you can create your own to suit your environment. (If this sample file fits the bill for you, you can skip down to the part about creating the display.msg file.)

The DEFAULT keyword specifies which boot option will be chosen once the timeout expires. The TIMEOUT option specifies how long to wait before booting the default option. This timeout is measured in one-tenth of a second; thus a value of 50 sets it for 5 seconds. The PROMPT option specifies whether the PXE software displays the boot: prompt to enable users to choose an operating system. The DISPLAY option displays a text file on the screen as an introduction. In this case, the file is called display.msg and must be placed in the root LTSP directory alongside the pxelinux.0 file. An example of this file is proposed a little later.

The three lines starting with LABEL linux define the linux option for booting. This is configured by the KERNEL and APPEND options, which you will notice are extracted from the original default file, as shown here:

DEFAULT vmlinuz ro initrd=initrd.img quiet splash

All that is needed now is the option for booting from the local hard drive, shown by the two lines starting LABEL localboot. These lines define the localboot option as used with the DEFAULT keyword earlier in the file. The only definition included in this option is the LOCALBOOT option, with a parameter of 0. This provides normal hard disk booting. Other parameters are available, as you can see by visiting the Syslinux home page, http://syslinux.zytor.com.

The display.msg file should contain some information that tells the user what to do to choose an operating system. Following is an example file that is suitable for the configuration just described. When creating this file, it is helpful to use a number of blank lines before the text actually begins. This has the effect of clearing the screen so that users don’t get confused by the PXELinux start-up text.

==================================================================

                    Welcome to the Multiboot System

                     The system will start in 5 seconds...

        for Linux users type :  linux
        at the boot: prompt and press <enter>

==================================================================

After rebooting the client, you should see the text from the display message file. It should look similar to that shown in Figure 5-15.

Image

Figure 5-15 Multiboot system in action

Changing Your IP Address

At some point it may become necessary to change the IP address of the server. Changing the IP address of a normal machine would not usually have much consequence on the client machine. However, in an LTSP environment, changing the IP address will result in clients being unable to log in. This is because when the LTSP root is built, it is populated with SSH authorization keys, which allow authentication between the client and the server without a password.

The procedure for solving this issue is fairly simple. First, log in to your server and then run the LTSP SSH key update script by typing the following command into the terminal and pressing Enter. You will be prompted for your password.

sudo ltsp-update-sshkeys


Tip

When entering your password, nothing is displayed on the screen, although your password is still being read by the computer. The password is not displayed for security reasons, but it is also not obfuscated. This prevents people who may be looking over your shoulder from seeing how many characters your password has.



Tip

It is possible here to update the SSH keys by simply restarting the network interface, using a command similar to the following one. You will need to replace <iface> with the interface identifier, usually something like eth0 or eth1.

sudo ifdown <iface> && sudo ifup <iface>

Once completed, your SSH keys will be updated, and after the clients reboot, they should be able to log in again.


Local Devices over LTSP

Since Ubuntu Edgy 6.10, Edubuntu has included the update to LTSP to allow what are called local devices. Plugging a USB storage device into a thin client machine, for example, will trigger the local devices mechanism, and the device will be correctly mounted and shown on the desktop of the client machine.

When using USB sticks with Ubuntu, you would normally have to unmount the device before removing it physically. This is so that Ubuntu has time to write all the data it needs to the USB stick and can safely unmount it. In the LTSP environment, using a USB stick is a little different. There is no unmount option because the data is written to the USB stick on a very regular basis. Hence you do not need to unmount it and can just remove it once the computer has finished writing information to it.

Local device support is set up by default in Edubuntu; however, to use it you must add to the fuse group the users who require access to such support. You can do this from the user manager. Start by going to System > Administration > Users and Groups option. From here, select the user to whom you wish to give local device access and click on the User Properties button. Click on the User Privileges tab, and from here tick the checkbox for allowing use of fuse filesystems, as shown in Figure 5-16.

Image

Figure 5-16 Setting fuse preferences

Sound over LTSP

Since Ubuntu Dapper 6.06, Edubuntu has the ability to play sound through the speakers of the client machine. For versions of Edubuntu prior to 6.10 and LTSP setups installed on top of Ubuntu, you must add an entry to the /opt/ltsp/i386/etc/lts.conf file to enable sound for client machines.

The easiest way to edit this file is to hold down Alt-F2, which will bring up the run command dialog box. Type in the following command:

gksudo "gedit /opt/ltsp/i386/etc/lts.conf"

Clicking OK will bring up an editing window. Make sure to have at least a [default] section in the lts.conf file where you will add the following line:

SOUND=True


Warning

Dapper 6.06 LTS is very particular about the SOUND=True statement. You must type it exactly as shown, taking extreme care with capital letters and so on.


For all versions after 6.10 of Edubuntu, this is already done for you, and sound should work on client machines out of the box.